SQL:按相似值对结果进行计数和分组的有效方法

SQL: Efficient way to count and group results by like value

我有一个 table 看起来像这样:

+----+-------+
| id | col2  |
+----+-------+
|  1 | a     |
|  2 | b     |
|  3 | ,b    |
|  4 | c     |
|  5 | d,a   |
|  6 | e,a,b |
+----+-------+

最有效的查询方式是什么以及return以下?

+------+----------+
| col1 | count_id |
+------+----------+
| a    |        3 |
| b    |        3 |
| c    |        1 |
| d    |        1 |
| e    |        1 |
+------+----------+

我想使用 case when 语句,但看起来很乱。

在 Presto 中,您可以将分隔列表拆分为一个数组,然后取消嵌套该数组。这为每个列表中的每个元素提供一条记录。剩下的只是聚合:

select s.colx, count(*) cnt 
from mytable t
cross join unnest(split(t.col2, ',')) as s(colx)
group by s.colx

如果你想要 distinct ids 的计数(以防分隔列表中有重复项):

select s.colx, count(distinct t.id) cnt 
from mytable t
cross join unnest(split(t.col2, ',')) as s(colx)
group by s.colx

好吧,您可能需要一个字符 table,其中包含可能出现在第二列中的所有字符。假设你确实有,你可以尝试加入方法:

WITH letters AS (
    SELECT 'a' AS col1 UNION ALL
    SELECT 'b' UNION ALL
    SELECT 'c' UNION ALL
    ...
    SELECT 'z'
)

SELECT
    t1.col1,
    COUNT(t2.col2) AS count_id
FROM letters t1
LEFT JOIN yourTable t2
    ON ',' || t2.col2 || ',' LIKE '%,' || t1.col1 || ',%'
GROUP BY
    t1.col1
ORDER BY
   t1.col1;

请注意,仅当 col2 恰好包含我们要报告的所有字母时,接受的答案才有效。如果不是,那么它会在输出中丢失信息。