【问题标题】:Count number of LIKE-matches per Entry计算每个条目的 LIKE 匹配数
【发布时间】:2014-06-02 22:15:34
【问题描述】:

我试着用一个简单的例子来解释我所说的匹配的意思:

我有一张这样的桌子myprods

id | name
1    galaxy s4 mini
2    samsung galaxy s4
3    galaxy galaxy s3
4    iphone 4s
5    apple iphone 4s

到目前为止我有这个查询:

SELECT *
FROM   myprods
WHERE  name LIKE "%samsung%" OR name LIKE "%galaxy%" OR name LIKE "%s4%"

我的查询结果是:

id | name
1    galaxy s4 mini
2    galaxy s4
3    galaxy galaxy s3

现在我不仅会返回匹配的行,还会返回命中数。如果其中一个 LIKE 短语适用于该行,则一次命中。因此,在这种情况下,我希望命中数为 0、1、2 或 3。这意味着:LIKE 短语 "%galaxy%" 不应计为 id=3 的两次命中,它只计为“命中”或“没有击中”。

现在的预期结果是:

id | name               | hits
1    galaxy s4 mini       2
2    samsung galaxy s4    3
3    galaxy galaxy s3     1

可能在一个高性能的 mysql 短语中? 还是我应该只选择上面查询的行,然后通过 PHP 中的strpos 将单个子字符串与返回的名称匹配?

【问题讨论】:

    标签: mysql string match


    【解决方案1】:

    在 MySQL 中,布尔表达式可以用作整数——0 表示假,1 表示真。因此,以下工作:

    SELECT p.*,
           ((name LIKE '%samsung%') + (name LIKE '%galaxy%') + (name LIKE '%s4%')) as hits
    FROM   myprods p
    WHERE  name LIKE '%samsung%' OR name LIKE '%galaxy%' OR name LIKE '%s4%';
    

    编辑:

    如果是 MySQL,也可以将此查询表示为:

    SELECT p.*,
           ((name LIKE '%samsung%') + (name LIKE '%galaxy%') + (name LIKE '%s4%')) as hits
    FROM   myprods p
    HAVING hits > 0;
    

    having 在此上下文中的使用是 SQL 扩展,在其他数据库中不起作用。但是,它确实允许查询引用列别名进行过滤,而不使用子查询。

    【讨论】:

    • 哦,看起来不错。与 Where 子句中只有 LIKE 短语的 SQL 语句相比,将其作为整数返回不会影响性能,对吗?
    • @tim 。 . .执行like 6 次而不是 3 次应该不会对性能产生一点影响。但是,编辑后的答案提供了另一种选择。
    • 我认为也许 mysql 会在内部组织它,这样它实际上不会因为重复的 LIKE 短语而变成 6 次 ;-) 但是是的,你的编辑非常好,谢谢: -)
    • 我想到的还有一件事:是否可以将匹配的字符数计算为总和?这意味着,samsunggalaxy 的命中将值得 7+6=13(仍然是 2 次命中),samsungs4 的 2 次命中将值得 7+ 2=9,因此较长的命中数会更多
    • 我刚刚想出了类似:((name LIKE '%samsung%')*7 + (name LIKE '%galaxy%')*6 + (name LIKE '%s4%'))*2 as hitlength 作为查询的补充。有用? :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多