即使未找到完全匹配,也会返回SQL查询结果

时间:2012-10-31 23:00:26

标签: php sql

我希望这个问题不是多余的。我想要完成的是让用户在页面上选择一堆复选框,如果没有匹配的行,则返回最接近的匹配记录。例如:

一个人检查[x]苹果[x]橙子[x]梨[x]香蕉

但表格如下:

Apples     Oranges      Pears     Bananas
 1             1           1        null
 1             1         null       1
 1             1         null       null

(显然我在这里错过了id列,但你得到了我认为的观点。)所以,期望的结果是仍然按照大多数匹配的顺序返回这三行,所以几乎就是他们现在的顺序。我只是不确定采取这样的事情的最佳方法是什么。我考虑过全文搜索,levenshtein函数,但我真的很喜欢返回精确匹配的想法。如果不需要,您无需使用代码。我只是希望被送往正确的方向。我已经看到了其他类似的问题,但我仍然不确定要走哪条路。

谢谢!

4 个答案:

答案 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 =未选中

相关问题