我有以下MySQL查询可以使用
SELECT *,
CONCAT( office, ' ', contactperson ) AS bigDataField
FROM webcms_mod_references
HAVING bigDataField REGEXP "one|two"
现在没有ORDER BY,如果: - bigDataField包含“one”此字段显示 - bigDataField包含“一二”这个字段显示为
现在它取决于首先显示其中一个的id,但是我希望首先显示具有更多匹配的那个!
我试过
SUM(
CASE WHEN bigDataField REGEXP "one|two"
THEN 1
ELSE 0 END
) AS matches
但这不起作用。谁能帮我。我认为最好的将是标题所说的从REGEXP中计算匹配的字符串。如果还有其他方法请解释。
REGEXP是用户输入,因此,我正在尝试在小型数据库上实现小型搜索。
答案 0 :(得分:2)
这是理论上的,而sqlfiddle已关闭,但您可能需要将REGEXP拆分为两个,这样您就可以计算匹配数。 REGEXP将返回0或1.要么匹配要么不匹配。不支持查找字符串中匹配的次数。
SELECT *,
CONCAT( office, ' ', contactperson ) AS bigDataField
FROM webcms_mod_references
HAVING bigDataField REGEXP "one|two"
ORDER BY (bigDataField REGEXP "one" + bigDataField REGEXP "two") DESC
答案 1 :(得分:1)
无法计算正则表达式的匹配数量。您可以做的是单独匹配它们并按每个匹配顺序排序。 EG:
SELECT *,
CONCAT( office, ' ', contactperson ) AS bigDataField
FROM webcms_mod_references
HAVING bigDataField REGEXP "one|two"
ORDER BY
CASE WHEN bigDataField REGEXP "one" AND bigDataField REGEXP "two" THEN 0
ELSE 1 -- The else should catch the "two" alone or the "one" alone because of the filtering
END
当然,你也可以在这里使用LIKE
,但也许你的正则表达式比这更复杂:)
答案 2 :(得分:0)
当我想要计算一些子字符串时,我会替换“ - ”长度,例如:
SELECT (
LENGTH('longstringlongtextlongfile') -
LENGTH(REPLACE('longstringlongtextlongfile', 'long', ''))
) / LENGTH('long') AS `occurrences`
我认为这是一个优雅的解决方案,用于计算“字符串”中出现多少次“长”的问题
答案 3 :(得分:0)
这不是这个问题的特别答案,但我认为它与它紧密相关...(并且希望能对来自Google等的人有所帮助)
因此,如果您使用PHP(如果未使用,则可能会继续阅读...),则可以以此来构建查询,在这种情况下,您可以这样做(关于@Moob很好的答案):
function buildSearchOrderBy(string $regex, string $columName, string $alternateOrderByColumName): string
{
if (
is_array(
$keywords = explode('|', $regex)
) === false or
empty($keywords) === true
) {
return $alternateOrderByColumName;
}
$orderBy = '(';
$i = 0;
foreach($keywords as $keyword)
{
$i++;
if($i > 1) $orderBy .= " + ";
$orderBy .= "IF((" . $columName . " REGEXP '" . $keyword . "')>0, " . (100 + strlen($keyword)) . ", 0)";
}
$orderBy .= ')';
return $orderBy;
}
因此,在这种情况下,每个匹配项的价值都超过100 +这么多的分数,即当前关键字中的字符数。每场比赛都从100开始,因为这确保了基础,因此第一个结果将是这些,总分源自更多的比赛,但无论如何在比例上价值都更长的关键字。
建立到一栏检查,但我认为您可以轻松进行更新。 如果将其复制到您的项目中,则仅使用这种方式(仅作为示例):
$orderBy = buildSearchOrderBy($regex, 'article.title', 'article.created');
$statement = "SELECT *
FROM article
WHERE article.title REGEXP '(" . $regex . ")'
ORDER BY " . $orderBy . " DESC"
;