获得满足SQL中最低条件的第一条记录

时间:2017-04-16 19:47:23

标签: mysql sql mariadb

我的主要目标是在列中搜索特定值(例如 word )。如果它不存在,想要找到第一个匹配 word% wor% wo% w%< / em>的

在“英语”中,查询的内容如下:“查找'单词'并返回(如果存在)。如果不存在,请查找与”单词“具有最大相同前缀的第一个单词。

我可以写

SELECT word FROM words WHERE word = 'word' or word LIKE 'word%' or ... LIMIT 1;

我试图按字母顺序排序,但它不起作用(我们来之前)。另外,不能以相反的顺序排序,或者'wordy'将出现在'word'之前。

我目前的想法是只调用数据库n次,其中n = length(word)。但我想知道SQL中是否存在任何类型的“短路OR” - 确切地说是MySQL / MariaDB。

示例

DB有'w','word','wording',想要通过'word'搜索并只检索'word'。

DB有'z','zab','zac','ze','zeb'想要通过'za'搜索并获得'zab'

3 个答案:

答案 0 :(得分:1)

听起来你正在寻找string distance algorithm。字符串距离算法告诉您将当前单词更改为所需单词需要多少更改。这个想法是你给你的所有单词一个字符串距离并按距离上升排序。完全匹配将为0,缺少或额外的字母将为1。

不完全是你的问题的答案,但我希望它实际上是你在寻找的。您可能也对word stems感兴趣,这将很好地与此相关。

修改

使用您的实际查询解决方案扩展我的答案。 添加一个功能:

CREATE FUNCTION `WORDRANK`(`a` VARCHAR(150), `b` VARCHAR(150)) RETURNS INT
BEGIN
    DECLARE rank INT DEFAULT 0;

    WHILE rank < LENGTH(a) DO
        IF rank = 0 AND b = a THEN RETURN rank;
        ELSEIF rank = 0 AND b LIKE CONCAT(a, "%") THEN RETURN rank + 1;
        ELSEIF b LIKE CONCAT(LEFT(a, LENGTH(a) - rank), "%") THEN RETURN rank + 2;
        END IF;
        SET rank = rank + 1;
    END WHILE;

    RETURN rank + 100;
END

然后创建一个存储过程:

CREATE PROCEDURE `getClosestMatch`(IN `q` VARCHAR(150))
BEGIN
    SELECT
        word
    FROM words
    WHERE word LIKE CONCAT(LEFT(q, 1),"%")
    ORDER BY WORDRANK(q, word), word
    LIMIT 1;
END

为了获得理想的结果,我们需要根据您在WORDRANK函数中定义的所需算法对每个单词进行排名。存储过程是如此,我们有一种执行查询的通用方法。

答案 1 :(得分:1)

假设:单词是ASCII,最小长度= 1,最大值<1。 &#39; ZZ&#39 ;. 假设:VARCHAR输入,没有跟踪空格。 假设:如果&#39;字&#39;不存在,但&#39;措辞&#39;并且&#39;罗嗦&#39;在那儿, 你想要&#39;措辞&#39;不是罗嗦&#39;。 也许并不简单,但只有一个SELECT语句......

return

答案 2 :(得分:0)

尝试以下查询:

SELECT word 
  FROM words
 WHERE word LIKE 'w%'
ORDER BY word;