【发布时间】:2021-04-16 02:11:45
【问题描述】:
初始数据(实际表包含超过2,000,000行):
+--------+--------+-------+
| note | factor | label |
+--------+--------+-------+
| note_1 | 1 | 2 |
+--------+--------+-------+
| note_1 | 1 | 3 |
+--------+--------+-------+
| note_1 | 2 | 4 |
+--------+--------+-------+
| note_2 | 123 | 2 |
+--------+--------+-------+
| note_2 | 123 | 3 |
+--------+--------+-------+
| note_2 | 2 | 4 |
+--------+--------+-------+
| note_3 | 456 | 4 |
+--------+--------+-------+
| note_4 | 434 | 5 |
+--------+--------+-------+
| note_5 | 456 | 3 |
+--------+--------+-------+
| note_5 | 456 | 4 |
+--------+--------+-------+
我想得到什么(进一步决赛桌):
+----+-----------------+
| id | notes |
+----+-----------------+
| 1 | {note_1,note_2} |
+----+-----------------+
| 2 | {note_4} |
+----+-----------------+
| 3 | {note_3,note_5} |
+----+-----------------+
更清楚:
我需要将 notes 按 factor 和 label 列分组。注释只能在结果表中出现一次。结果表应包含两列:id - 行号,notes - 注释数组。
我已经写了一个查询来分组factor和label:
select row_number() over (order by factor) as id
, array_agg(note order by note) as notes
from test_brand
group by factor, label
它给出了这些结果:
+---+-----------------+
| 1 | {note_1} |
+---+-----------------+
| 2 | {note_1} |
+---+-----------------+
| 3 | {note_2} |
+---+-----------------+
| 4 | {note_2} |
+---+-----------------+
| 5 | {note_1,note_2} |
+---+-----------------+
| 6 | {note_4} |
+---+-----------------+
| 7 | {note_5} |
+---+-----------------+
| 8 | {note_3,note_5} |
+---+-----------------+
但我不知道如何从这里进入决赛桌。
如果我们省略标识符并返回普通数字,那么这个任务看起来就像集合的并集(实际上它是)。
假设我们有 8 个集合:{1}、{1}、{2}、{2}、{1,2}、{4}、{5}、{3,5}。我们需要得到三个集合:{1,2}、{4}、{3,5}。
在我看来它是如何发生的:
集合 {1}、{1}、{2}、{2}、{1,2} 合并为一个集合 {1,2},因为 {1} 和 {2} 与 {1,2} 有交集.
集合 {3,5}、{5} 合并为一组 {3,5},因为 {5} 和 {3,5} 之间存在交集。
集合 {4} 不与任何人相交,因此保持原样。
【问题讨论】:
标签: sql postgresql merge concatenation postgresql-performance