我希望这个问题不是多余的。我想要完成的是让用户在页面上选择一堆复选框,如果没有匹配的行,则返回最接近的匹配记录。例如:
一个人检查[x]苹果[x]橙子[x]梨[x]香蕉
但表格如下:
Apples Oranges Pears Bananas
1 1 1 null
1 1 null 1
1 1 null null
(显然我在这里错过了id列,但你得到了我认为的观点。)所以,期望的结果是仍然按照大多数匹配的顺序返回这三行,所以几乎就是他们现在的顺序。我只是不确定采取这样的事情的最佳方法是什么。我考虑过全文搜索,levenshtein函数,但我真的很喜欢返回精确匹配的想法。如果不需要,您无需使用代码。我只是希望被送往正确的方向。我已经看到了其他类似的问题,但我仍然不确定要走哪条路。
谢谢!
答案 0 :(得分:2)
编写一个查询,用于累加匹配的列数,并按此总计对行进行排序。 E.g。
SELECT *
FROM mytable
ORDER BY COALESCE(Apples, 0) = $apples + COALESCE(Oranges, 0) = $oranges + ... DESC
答案 1 :(得分:1)
按分数排序很容易......
SELECT fb.ID, fb.Apples, fb.Oranges, fb.Pears, fb.Bananas
FROM FruitBasket fb
ORDER BY
CASE WHEN @Apples = fb.Apples THEN 1 ELSE 0 END
+ CASE WHEN @Oranges = fb.Oranges THEN 1 ELSE 0 END
+ CASE WHEN @Pears = fb.Pears THEN 1 ELSE 0 END
+ CASE WHEN @Bananas = fb.Bananas THEN 1 ELSE 0 END
DESC, ID
但是,这会导致表扫描(即使使用TOP)。最后一条记录可能比目前发现的记录更好,所以必须阅读每条记录。
您可以考虑使用标记系统,例如this
Content --< ContentTag >-- Tag
将以这种方式查询:
SELECT ContentID
FROM ContentTag
WHERE TagID in (334, 338, 342)
GROUP BY ContentID
ORDER BY COUNT(DISTINCT TagID) desc
此查询将使用ContentTag.TagId的索引。
答案 2 :(得分:0)
这很简单,但你可以使用IFNULL()
(MySQL或你的数据库的等价物)来返回匹配的总和并在ORDER BY
// columns and weighting score
$types = array("oranges"=>1, "apples"=>1, "bananas"=>1, "pears"=>1);
$where = array();
// loop through the columns
foreach ($types as $key=>&$weight){
// if there is a match in $_REQUEST at it to $where and increase the weight
if (isset($_REQUEST[$key])){
$where[] = $key . " = 1";
$weight = 2;
}
}
// build the WHERE clause
$where_str = (count($where)>0)? "WHERE " . implode(" OR ", $where) : "";
// build the SQL - non-null matches from the WHERE will be weighted higher
$sql = "SELECT apples, oranges, pears, bananas, ";
foreach ($types as $key=>$weight){
$sql .= "IFNULL({$key}, 0, {$weight}) + ";
}
$sql .= "0 AS score FROM `table` {$where_str} ORDER BY score DESC";
假设选择“oranges”和“apples”,您的SQL将是:
SELECT apples, oranges, pears, bananas,
IFNULL(apples, 0, 2) + IFNULL(oranges, 0, 2) + IFNULL(pears, 0, 1) + IFNULL(bananas, 0, 1) + 0 AS score
FROM `table`
WHERE oranges = 1 OR apples = 1
ORDER BY score DESC
答案 3 :(得分:0)
按照复选框/数据匹配的总和降序
SELECT * FROM table
ORDER BY (COALESE(Apple,0) * @apple) + (COALESE(Orange,0) * @orange) ..... DESC
其中@apple / @orange表示用户选择:1 =已选中,0 =未选中