MySQL:计算每个条目的LIKE匹配数

tim*_*tim 6 php mysql string match

我试着通过一个简单的例子来解释我的意思:

我有这样一张桌子myprods:

id | name
1    galaxy s4 mini
2    samsung galaxy s4
3    galaxy galaxy s3
4    iphone 4s
5    apple iphone 4s
Run Code Online (Sandbox Code Playgroud)

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

SELECT *
FROM   myprods
WHERE  name LIKE "%samsung%" OR name LIKE "%galaxy%" OR name LIKE "%s4%"
Run Code Online (Sandbox Code Playgroud)

我的查询结果是:

id | name
1    galaxy s4 mini
2    galaxy s4
3    galaxy galaxy s3
Run Code Online (Sandbox Code Playgroud)

现在我不仅返回匹配的行,还返回命中数.如果其中一个LIKE-phrase适用于该行,那么ONE命中.因此,在这种情况下,我希望命中为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
Run Code Online (Sandbox Code Playgroud)

在高性能的mysql短语中可能吗?或者我应该只选择上面带有我的查询的行,然后通过strposPHP 将单个子串匹配到返回的名称?

提前致谢

Gor*_*off 11

在MySQL中,布尔表达式可以用作整数 - 0表示false,1表示true.所以,以下工作:

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%';
Run Code Online (Sandbox Code Playgroud)

编辑:

如果是MySQL,您还可以将此查询表达为:

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

采用having在这方面是一个SQL扩展和其他数据库无法正常工作.但是,它允许查询引用列别名进行过滤,而不使用子查询.

  • @tim...做'喜欢'6次而不是3次不应该对性能产生一点影响.但是,编辑的答案提供了另一种选择. (2认同)