2

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

一个人检查 [x]Apples [x]Oranges [x]Pears [x]Bananas

但是表格看起来像这样:

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

(很明显,我在这里错过了 id 列,但你明白我的意思。)所以,期望的结果是让这三行仍然按照大多数匹配的顺序返回,几​​乎是它们现在的顺序。我只是不确定采取此类事情的最佳方法是什么。我考虑过全文搜索,即 levenshtein 函数,但我真的很喜欢返回完全匹配(如果存在)的想法。如果不需要,您无需详细说明代码。我只是希望被送到正确的方向。我见过其他类似的问题,但我仍然不确定该走哪条路。

谢谢!

4

4 回答 4

2

编写一个查询,将匹配的列数相加,并按此总数对行进行排序。例如

SELECT *
FROM mytable
ORDER BY COALESCE(Apples, 0) = $apples + COALESCE(Oranges, 0) = $oranges + ... DESC
于 2012-10-31T23:05:02.687 回答
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)。最后一条记录可能比目前找到的记录更匹配,因此必须读取每条记录。


你可以考虑一个标签系统,像这样

Content --< ContentTag >-- Tag

将以这种方式查询:

SELECT ContentID
FROM ContentTag
WHERE TagID in (334, 338, 342)
GROUP BY ContentID
ORDER BY COUNT(DISTINCT TagID) desc

此查询将使用 ContentTag.TagId 上的索引。

于 2012-10-31T23:47:49.083 回答
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";

假设选择“橙子”和“苹果”,您的 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
于 2012-10-31T23:07:46.583 回答
0

按复选框/数据匹配的总和降序排列

SELECT * FROM table
ORDER BY (COALESE(Apple,0) * @apple) + (COALESE(Orange,0) * @orange) ..... DESC

其中@apple / @orange 代表用户选择:1 = 选中,0 = 未选中

于 2012-10-31T23:42:35.603 回答