Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/245.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 返回SQL查询结果,即使未找到完全匹配的结果_Php_Sql - Fatal编程技术网

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

Php 返回SQL查询结果,即使未找到完全匹配的结果,php,sql,Php,Sql,我希望这个问题不是多余的。我试图完成的是让用户在页面上选择一组复选框,如果没有匹配行,则返回最接近的匹配记录。例如: 一个人检查[x]苹果[x]桔子[x]梨[x]香蕉 但该表如下所示: Apples Oranges Pears Bananas 1 1 1 null 1 1 null 1 1 1 null

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

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

但该表如下所示:

Apples     Oranges      Pears     Bananas
 1             1           1        null
 1             1         null       1
 1             1         null       null
(很明显,我错过了这里的id列,但我想你明白了。)因此,理想的结果是,这三行仍然按照大多数匹配的顺序返回,所以它们的顺序与现在差不多。我只是不确定采取这样的方式最好。我考虑过全文搜索,levenshtein函数,但我非常喜欢返回精确匹配(如果存在)的想法。如果不需要,您无需详细介绍代码。我只是希望被派往正确的方向。我见过其他类似的问题,但我仍然不确定该怎么办


谢谢

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

SELECT *
FROM mytable
ORDER BY COALESCE(Apples, 0) = $apples + COALESCE(Oranges, 0) = $oranges + ... DESC

这相当简单,但您只需使用
IFNULL()
(MySQL,或您的DB的等效项)返回匹配项的总和,并按
顺序使用它

// 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

按复选框/数据匹配项之和降序排列

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

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

很容易按分数排序

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)。最后一条记录可能比目前找到的记录更匹配,因此必须读取每条记录


<>你可以考虑一个标签系统,比如


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

不确定我是否理解正确,但如果我这样做,它只会按照orances DESC、pears DESC、bananas DESC的顺序工作。
表中的这些列是否包含除1或NULL以外的值?如果一个匹配被认为是积极的,那么错误的匹配应该被认为是消极的吗?要将NULL视为匹配所有内容还是不匹配?也许它意味着未知,也许它意味着丢失?Null实际上是0。我想做一个二进制。如果列已标记,则为1;如果尚未标记,则为null。我的目的是不让空值引起怀疑。这是如何使用来自复选框的输入的?好的,很好!我要深入研究,跟随你们的领导做一些研究。我会让你知道我有多公平。感谢您的及时回复。谢谢。我正计划用php传递变量,哈哈。我正在制作一个工作网站。我可能应该具体说明一下。因此,用户选择他们拥有的学位,然后返回带有这些学位标记的作业。@user1789907因为我手头有太多时间,请参见编辑。
Content --< ContentTag >-- Tag
SELECT ContentID
FROM ContentTag
WHERE TagID in (334, 338, 342)
GROUP BY ContentID
ORDER BY COUNT(DISTINCT TagID) desc