Sql 聚合行以获得不带子集的唯一数组
初始数据实际表包含超过2000000行:Sql 聚合行以获得不带子集的唯一数组,sql,postgresql,merge,concatenation,postgresql-performance,Sql,Postgresql,Merge,Concatenation,Postgresql Performance,初始数据实际表包含超过2000000行: +--------+--------+-------+ | note | factor | label | +--------+--------+-------+ | note_1 | 1 | 2 | +--------+--------+-------+ | note_1 | 1 | 3 | +--------+--------+-------+ | note_1 | 2 | 4 | +----
+--------+--------+-------+
| 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-行号,注释-注释数组
我已经向group by factor and label编写了一个查询:
选择“按系数排序”上的行号作为id
,数组_agg注释按注释顺序排列为注释
来自test_品牌
按因子分组,标签
它给出了以下结果:
+---+-----------------+
| 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},{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}不与任何人相交,因此它保持原样。可能有更有效的方法,但这样做: 以cte为例 选择minrn作为rn,notes-以低成本删除重复 从…起 选择按因子排序的行数,标签为rn-按因子排序,标签?! ,数组_agg注释按注释顺序排列为注释 来自test_品牌 按因子分组,标签 附属的 按注释分组 选择按rn排序的行编号作为rn,注释 来自cte c 不存在的地方 从cte c1中选择 其中c1.notes@>c.notes 和c1.rn c.rn 1号订单; 小提琴 初始查询后,删除CTE中的重复项并记住最小行数 在最终选择中,删除该集合包含在除自身之外的其他集合中的所有行。使用另一个row_number实例压缩行号。 瞧 优化性能 200多万行 如果note可以是整数而不是字符串类型,那么计算速度将大大加快,在安装额外的模块后更是如此,该模块为整数数组提供了更快的@>运算符实现 如果来自CTE的派生表仍然很大,那么创建一个临时表、添加一个索引并进行分析是值得的!,并根据该临时表运行外部选择: 将临时表tmp创建为 选择minrn作为rn,notes-以低成本删除重复 从…起 选择按系数排序的行数,标签为rn ,数组_agg注释按注释顺序排列为注释 来自test_品牌 按因子分组,标签 附属的 按注释分组 ; 使用gin notes gin\uuu int\u ops在tmp上创建索引; 分析tmp; 选择按rn排序的行编号作为rn,注释 来自tmp c 不存在的地方 从tmp c1中选择 其中c1.notes@>c.notes 和c1.rn c.rn 1号订单; 见:
谢谢你的回答!我不确定,但出了点问题。您可以在这里看到运行示例:我只添加了两个新行:note_7、123、2和note_8、656、8。正确的结果是:{note_1,note_2,note_7}{note_4}{note_3,note_5}{note_8},但是运行脚本会得到以下结果:{note_1,note_2}{note_2,note_7}{note_4}{note_3,note_5}{note_8}@ErwinBrandstetter。不知何故,你开始回答可能有更有效的方法是认知不协调。几乎从定义上讲,我希望你的答案是在博士后做事情的最有效的方式。@Moon但是note_1和note_7没有共享因子,label?@Gordon:这次我不太确定。@>这是一个没有索引的昂贵操作。关于优化的补充对我来说更好。不过,我觉得可能有更多的潜力来加速。而且,谢谢你。@ErwinBrandstetter,是的,他们不是。但是注释1共享因子,标签为注释2,注释2共享因子,标签为注释7。然后我们需要把他们都聚在一起。换句话说:{1},{1,2},{2,7}应该创建一组{1,2,7}。
+---+-----------------+
| 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} |
+---+-----------------+