[英]MySQL Count number of substring occurrences in column
使用MySQL,我试图计算每一行中一个子串的出现次数。
在下面的示例表中,字符串“art”在“条款”列中出现三次,因此它的计数为3。
示例表:
TERMS
art
artistic
painting
elephant
art deco
paint
paintings
期望的输出:
TERMS COUNT
art 3
artistic 1
painting 2
elephant 1
art deco 1
paint 2
paintings 1
编辑:
作为一个起点,我知道:
SELECT terms, COUNT(*)
FROM table
GROUP BY terms
将输出每个完整术语字符串的出现次数。 对于子字符串匹配,我认为这可能涉及子查询。
试过以下,但每个计数都是1。
SELECT terms, ROUND((CHAR_LENGTH(terms) - CHAR_LENGTH(REPLACE(terms, terms, ""))) / CHAR_LENGTH(terms)) AS count
FROM table
GROUP BY terms
我会写这个,首先编写一个只返回我们想要返回的术语列表的查询。 例如:
SELECT t.terms
FROM `table` t
GROUP BY t.terms
然后将其包装在parens中并将其用作内联视图...
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(REPLACE( w.terms ,'\\','\\\\'),'_','\_'),'%','\%')
^^^^^^^^ ^^^^^^^^^^^^^
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.