在 SQL 中,根据分组创建对并计算它们的频率

Posted

技术标签:

【中文标题】在 SQL 中,根据分组创建对并计算它们的频率【英文标题】:In SQL, create pairs based on a grouping and count their frequency 【发布时间】:2021-02-14 06:47:52 【问题描述】:

我想要的是为每个 ID 创建第 2 列的 DISTINCT 对并按计数排列它们。 我们以这张表为例:

CREATE TABLE mytable
    (`ID` int, `C2` varchar(1), `C3` varchar(2))
;
    
INSERT INTO mytable
    (`ID`, `C2`, `C3`)
VALUES
    (1, 'A',' a1'),
    (1, 'B', 'b1'),
    (2, 'A', 'a2'),
    (3, 'A', 'a3'),
    (3, 'C', 'c3'),
    (3, 'A', 'a4'),
    (4, 'A', 'a1'),
    (4, 'B', 'b4'),
    (4, 'A', 'a2'),
    (4, 'D', 'd1');

对于 1,对将是 A-B。 对于 2,一个将不存在。 对于 3,对将是 A-C。 对于 4,对将是 A-B、A-D 和 B-D。

所以输出将是:

| Pair | Cnt |
| A-B  | 2   |
| A-C  | 1   |
| A-D  | 1   | 
| B-D  | 1   |

这是我们可以在 SQL 中使用 GROUP_CONCAT 之类的东西吗? 几天来我一直在思考这个问题,但仍然想不出一个简单的解决方案。

谢谢!

【问题讨论】:

【参考方案1】:

我认为这是一个自联接和计数不同的。一种方法是:

select t1.c2, t2.c2, count(distinct t1.id) as cnt
from t t1 join 
     t t2
     on t1.id = t2.id and t1.c2 < t2.c2
group by t1.c2, t2.c2
order by cnt desc;

根据您的数据,先删除重复项然后加入可能会更有效:

with tt as (
      select distinct t.id, t.c2
      from t
     )
select t1.c2, t2.c2, count(t1.id) as cnt
from tt t1 join 
     tt t2
     on t1.id = t2.id and t1.c2 < t2.c2
group by t1.c2, t2.c2
order by cnt desc;

【讨论】:

天哪,我意识到这很简单,但我把问题复杂化了。猜猜我没有考虑对字符使用 【参考方案2】:

您可以自行加入和聚合:

select t1.c2 c21, t2.c2 c22, count(distinct t1.id) cnt 
from mytable t1
inner join mytable t2
    on  t1.id = t2.id
    and t1.c2  < t2.c2
group by t1.c2, t2.c2

【讨论】:

您好!我将您的a 更改为c2,但我的结果中有重复... | AB | 3 ||交流 | 2 ||广告 | 2 || BD | 1 |

以上是关于在 SQL 中,根据分组创建对并计算它们的频率的主要内容,如果未能解决你的问题,请参考以下文章

根据频率创建音频文件

计算列表中单词的频率并按频率排序

R语言分组绘制频率概率图

SQL percentile_cont vs SPSS 频率百分位数

使用 .Net/C# 计算集合的频率分布

事件的 SQL 频率