当使用LIKE时,如何按大多数匹配排序MySQL结果


How to sort MySQL results by most matches when using LIKE

我目前正在处理一个查询,该查询必须显示来自特定表的所有文章的列表,但它必须根据搜索表单对列表进行排序,以便首先显示包含最多/最佳匹配的文章,而那些没有任何匹配的文章将按字母顺序最后显示。

我已经使这个代码工作得很好,虽然我找不到一种方法来按大多数命中/相关性排序匹配。

下面是我的代码:
$search = $_POST["searhwords"];
$search = preg_replace('/'s+/', ' ',$search);
$SearchQueryArray = str_replace(",", "", $search);
$SearchQueryArray = str_replace(" ", ",", $SearchQueryArray);
$SearchQueryArray = explode(',', $SearchQueryArray);

$outputtt1 = '';
$outputtt2 = '';
foreach ( $SearchQueryArray as $queryword )
{
    $outputtt1 .= "title LIKE '%".$queryword."%' OR ";  
    $outputtt2 .= "title NOT LIKE '%".$queryword."%' AND ";  
}
$outputtt1 = rtrim($outputtt1, ' OR ');
$outputtt2 = rtrim($outputtt2, ' AND ');


$query_for_result = mysql_query("SELECT * from mytable 
WHERE ".$outputtt1."
union all
SELECT * from mytable 
WHERE ".$outputtt2."
");

所以我需要找到一种方法来排序包含匹配项的文章,以便包含大多数匹配项的文章首先排序。

你可以在这里看到我制作的脚本:http://www.genius-webdesign.com/test/querytest.php

下面是执行此操作的SQL:

select t.*
from mytable
order by ((title like '%keyword1%') +
          (title like '%keyword2%') +
          (title like '%keyword3%') +
          . . .
          (title like '%keywordn%')
         ) desc;

MySQL将布尔表达式视为数字,true为1。因此,这将计算匹配的次数。

顺便说一下,如果您的数据有任何大小,您可能会发现全文搜索比使用like更有效。

编辑:

计算关键字的数量有点挑战性,但你可以这样做:

order by ((length(replace(title, 'keyword1', 'x')) -
           length(replace(title, 'keyword1', '')
          ) +
          (length(replace(title, 'keyword2', 'x')) -
           length(replace(title, 'keyword2', '')
          ) +
          . . .
          (length(replace(title, 'keywordn', 'x')) -
           length(replace(title, 'keywordn', '')
          )
         );

计算一个关键字出现的次数比仅仅查找它出现的位置要麻烦得多。

另一种方法是使用全文搜索

SELECT *, 
  MATCH('title') AGAINST($_GET['query']) * 10 as score1, 
  MATCH('content') AGAINST($_GET['query']) * 5 AS score2
FROM articles
WHERE MATCH (title, content) AGAINST($_GET['query'])
ORDER BY (score1) + (score2) DESC;

如果需要,可以这样修改表

ALTER TABLE articles ENGINE = MYISAM;
ALTER TABLE articles ADD FULLTEXT(title, content);