从逗号分隔字符串中按成员分组的mysql

从逗号分隔字符串中按成员分组的mysql,mysql,group-by,Mysql,Group By,我有一张超过一百万行的桌子: id | names 1 | sarah johnson 2 | anna smith;deborah cuoco 3 | sarah johnson;anna smith 我想执行一个将返回的查询 name | occurences sarah johnson | 2 anna smith | 2 deborah cuoco | 1 如果名称有时不包含多个条目,那么它将非常简单: SELECT names, count(id) a

我有一张超过一百万行的桌子:

id | names
1  | sarah johnson
2  | anna smith;deborah cuoco
3  | sarah johnson;anna smith
我想执行一个将返回的查询

name          | occurences
sarah johnson | 2
anna smith    | 2
deborah cuoco | 1
如果名称有时不包含多个条目,那么它将非常简单:

SELECT names, count(id) as occurences
FROM table
GROUP BY names
ORDER BY occurences DESC
但我不知道如何处理包含多个值的名称,在本例中,这些值由半列分隔


有没有一种方法可以在单个查询中实现这一点?

如果任何一行中只有少量这样的名称,您可以通过一些操作将其取出:

SELECT substring_index(substring_index(t.names, ';', n.n), ';', -1) as name,
       count(*) as occurences
FROM table t cross join
     (select 1 as n union all select 2 union all select 3) n
WHERE n.n <= length(t.names) - length(replace(t.names, ';', '')) + 1
GROUP BY name
ORDER BY occurences DESC;

这将从名称字符串中提取第n个元素。where子句确保只为包含x个元素的字符串提取x个元素,否则,最后一个元素将被过度计算。上述方法最多适用于名称中的三个名称。

ty用于尝试,但这似乎不起作用。首先,它在where子句中抛出一个未知列名错误。出于某种原因,它不允许在where子句中使用别名。如果我重复子字符串_indexsubstring _indexnames“;”,n、 n,“;”-1则查询可以工作,但只要有2个元素,它就会对姓氏进行过度计数。您应该通过规范化数据来重新考虑您的存储格式。不要将所有名称以逗号分隔的形式存储在一列中,而是创建以下表:其中每行仅包含一个名称的用户表,以及将包含用户id链接到用户表的行的链接表。这样,您的查询将变得更加简单,并且可以索引。请注意,您无法以当前格式有效地为数据编制索引,因此它将始终是缓慢的。我已经决定这样做。。我最初不是设计这个表的,它来自一个巨大的2gb csv转储。。我想抄近路,但我想我别无选择。谢谢你的反馈