我会先写一个查询,只是返回我们要返回术语列表写这篇文章。例如:
SELECT t.terms
FROM `table` t
GROUP BY t.terms
然后包裹在括号并用它作为内嵌视图...
SELECT w.terms
FROM (SELECT t.terms
FROM `table` t
GROUP BY t.terms
) w
ORDER BY w.terms
这样,我们可以做一个连接操作来寻找匹配的行,并获得了计数。假设terms
不包含下划线(_
)或百分比(%
)字符的保证,我们可以使用LIKE
比较。
鉴于我们列表中的每个术语至少会出现一次,我们可以使用内部联接。在更一般的情况下,我们可能希望返回零计数,我们将使用外连接。
SELECT w.terms
, COUNT(1) AS `COUNT`
FROM (SELECT t.terms
FROM `table` t
GROUP BY t.terms
) w
JOIN `table` c
ON c.terms LIKE CONCAT('%', w.terms ,'%')
GROUP BY w.terms
ORDER BY w.terms
在LIKE
比较,百分号是通配符匹配任何字符(零个,一个或更多)。
如果有可能terms
确实包含下划线或百分号字符,我们可以将它们转义,以便它们不被LIKE比较视为通配符。像这样的表达应该做的伎俩:
REPLACE(REPLACE(w.terms ,'_','\_'),'%','\%')
所以我们不得不这样的查询:
SELECT w.terms
, COUNT(1) AS `COUNT`
FROM (SELECT t.terms
FROM `table` t
GROUP BY t.terms
) w
JOIN `table` c
ON c.terms LIKE CONCAT('%',REPLACE(REPLACE(w.terms ,'_','\_'),'%','\%'),'%')
GROUP BY w.terms
ORDER BY w.terms
还有其他的查询模式,将返回指定的结果。这只是一种方法的演示。
注意:在这个问题的例子,每一个terms
那是另一个terms
一子,子字符串匹配出现在开始术语。此查询还会查找匹配项不在开头的位置。
例如dartboard
将被视为匹配art
的查询可以修改,以符合仅出现在开始的其他terms
terms
。
随访
随着数据。例如,返回:
terms COUNT matched_terms
--------- -------- -------------------------
art 3 art,art deco,artistic
art deco 1 art deco
artistic 1 artistic
elephant 1 elephant
paint 3 paint,painting,paintings
painting 2 painting,paintings
paintings 1 paintings
除了COUNT(1)
骨料,我还包括在选择列表中的另一种表达。这不是必需的,但它确实提供了关于哪些术语被认为是匹配的一些附加信息。
GROUP_CONCAT(DISTINCT c.terms ORDER BY c.terms) AS `matched_terms`
注意:如果有一种可能性,即terms
包含反斜杠字符,就可以逃避这些字符以及使用替换另一个
REPLACE(REPLACE(REPLACE(w.terms ,'\\','\\\\'),'_','\_'),'%','\%')
^^^^^^^^ ^^^^^^^^^^^^^
请与我们分享您的试验。 –
你的替换函数用它自己替换每一行的术语;在我的答案中看看建议1和2。 – MohaMad