Sql 如果阵列重叠,则折叠多行阵列
我在PostgreSQL 9.3中有一个表,其中包含一列 每行包含一个数组。我正试图找到一种崩溃的方法 共享相同元素的数组行 例子 简单重叠 给定以下两行和数组:Sql 如果阵列重叠,则折叠多行阵列,sql,arrays,postgresql,Sql,Arrays,Postgresql,我在PostgreSQL 9.3中有一个表,其中包含一列 每行包含一个数组。我正试图找到一种崩溃的方法 共享相同元素的数组行 例子 简单重叠 给定以下两行和数组: { 1, 2, 3 } { -5, 3, 6, 9 } 结果将是一行,其中包含: { -5, 1, 2, 3, 6, 9 } 这是因为两个数组中都存在“3”。请注意,“3”不会重复 多次重叠 同样的重叠概念也适用于表中任意位置的多行: { 1, 2, 3 } { 100, 200, 300 } { 3, 4, 5 } { 5, 6
{ 1, 2, 3 }
{ -5, 3, 6, 9 }
结果将是一行,其中包含:
{ -5, 1, 2, 3, 6, 9 }
这是因为两个数组中都存在“3”。请注意,“3”不会重复
多次重叠
同样的重叠概念也适用于表中任意位置的多行:
{ 1, 2, 3 }
{ 100, 200, 300 }
{ 3, 4, 5 }
{ 5, 6, 7 }
所需的输出将是两行:
{ 1, 2, 3, 4, 5, 6, 7}
{ 100, 200, 300 }
从结果返回的数组应该是唯一的,并且彼此之间不共享任何元素
我试过的
我使用了带函数的“带递归”查询,但无法找到正确的查询
提供了一个要使用的示例表(它模仿了第二个示例),也可以使用以下内容构建:
创建表测试(
arr整数[]
);
插入测试(arr)值(“{1,2,3}”);
插入测试(arr)值(“{100200300}”);
插入测试(arr)值(“{3,4,5}”);
插入测试(arr)值(“{5,6,7}”);
好的,很艰难。请查看此查询:
;with recursive minelem AS(
select arr, MIN(unnest) minel from (select arr, unnest(arr) from test) a group by arr),
testwithrn as(
select arr, row_number() over (order by minel) rn from minelem
),
cte(arr, rn, counter, grp) as(
select arr, rn, 1, 1 from testwithrn where rn = 1
union all
select
case when array_length(a.arr & b.arr, 1) > 0 then a.arr | b.arr else b.arr end,
b.rn,
case when array_length(a.arr & b.arr, 1) > 0 then a.counter + 1 else 1 end,
case when array_length(a.arr & b.arr, 1) > 0 then a.grp else a.grp + 1 end
from cte a inner join testwithrn b
on b.rn > a.rn
),
grouped as(
SELECT arr, counter, grp,
row_number() over (partition by grp order by counter desc) rn from cte)
select distinct arr from grouped where rn = 1
您可以在上面的查询中测试不同的CTE,以了解我是如何提出解决方案的。这里的关键是使用运算符|合并数组,如a.arr | b.arr
有一个名为
cte
的递归查询,它统计不同集合组中每个集合的出现次数。您可以将最后一行替换为select*from cte order by grp,counter
,以查看递归构建集合时counter
和grp
如何更改。对于这类问题,如果您提供了一个可用的示例表,那真是太好了。@CraigRinger这是一个整洁的网站。我想不出来,但这里有一个可用的表:。继续并将其添加到问题中。@trevor,嗯,有趣的查询。你不能用递归的自动加入,也不能在递归项上使用子查询,我认为你不能用聚合来实现这一点,除非你有办法通过重叠项对进行分组,我不相信这是可能的。您可能必须使用递归SQL函数。单次通过是从测试A内部连接测试b中选择uniq(array_cat(A.arr,b.arr))(b.arr>A.arr和A.arr&&b.arr)
,但这并没有多大帮助。如果表足够小,您可以用python这样的编程语言来完成它?