查找包含文本但在字段开头优先匹配的字段

时间:2013-07-29 14:22:16

标签: mysql

这是一个非常简单的问题。

我想查找文本字段包含用于填充表单中自动填充字段的文本的记录。挑战在于我想将结果限制在前20个记录中,但是优先考虑场地开始时的匹配。

我现在如何执行此操作是为{10}执行field LIKE "%term"的查询,然后将记录追加到field LIKE "%term%"为10。它需要两次搜索。

只用一个表格查询就可以做到这一点吗?按字段中的匹配位置排序?

3 个答案:

答案 0 :(得分:4)

是的,可以在第一次出现搜索字符串时进行排序。 (我假设你想写字段LIKE“term%”。)

SELECT *, LOCATE('term', field) as rev_score FROM table WHERE field LIKE "%term%" ORDER BY rev_score DESC LIMIT 20;

然而,这个查询很可能比字段“term%”慢得多(假设你在字段上有索引)。

  • 在您的情况下,字段LIKE“term%”可以由字段上的索引来实现,从而导致范围查询但仍然很快。
  • 字段LIKE“%term%”LIMIT 10如果您不使用订单仍然可以快速(呃)。统计上比我编写的解决方案快2倍,具体取决于搜索词和数据分布。原因是因为MySQL将开始扫描表中搜索“term”(这里不能使用索引)。当它找到10个元素时它会停止。这可以在表格的开头。
  • 我写的内容将导致MySQL对整个表进行全面扫描,并检查每个行的“term”而不是计算值上的filesort。可能是单个表查找可能发生的最糟糕的事情。

我会说尝试两个版本并使用更快的版本。或者,如果您的数据集很大,您可以查看MySQL的全文搜索功能(MYISAM拥有它,InnoDB也支持MySQL 5.6)。

答案 1 :(得分:1)

智能!我不知道是否可能,但我知道如何做得更好一点:

<?php

$q = 'term';
$limit = 20;

$first = mysql_query("SELECT * FROM some_table WHERE name LIKE '%$q' ORDER BY name LIMIT $limit");
$first_len = !$sql?0:mysql_num_rows($first);
$limit -= $first_len;
$second = mysql_query("SELECT * FROM some_table WHERE name LIKE '%$q%' LIMIT $limit");
$second_len = !$sql?0:mysql_num_rows($second);

if (!$first_len && !$second_len) {
    exit('No results found.');
}

function handleSearchResultRow($row) {
    echo $row['name'].'<br/>';
}

if ($first_len)
    while ($row = mysql_fetch_array($first))
        handleSearchResultRow($row);

if ($second_len)
    while ($row = mysql_fetch_array($second))
        handleSearchResultRow($row);

?>

多田!你会得到相同的结果,但代码稍多一些!这将确保最多总共有20个结果,结果从术语开始!

如果你真的想要“按字段中的匹配位置排序”,那么我认为你必须创建一个包含所有结果的数组并用php strpos()对其进行排序。但SQL非常强大,并且可能也有能力做到这一点。请发布另一个答案,告诉我你是否知道如何做到这一点。 :)

答案 2 :(得分:1)

我愿意:

SELECT * FROM table WHERE field LIKE '%term%' order by IF(field REGEXP '^term.*',0,1),field LIMIT 20;