【问题标题】:Unions of intersecting sets相交集的并集
【发布时间】:2017-04-25 19:26:15
【问题描述】:

我有一个代表记录集的表格,例如

set_id | record_id
     a |         1
     a |         2
     a |         3
     b |         2
     b |         4
     b |         5
     c |         6
     c |         7
     d |         9
     d |        11
     e |        10
     f |        11
     f |        12   

我想产生这样的输出

output
{1, 2, 3, 4, 5}
{6, 7}
{9, 11, 12}
{10}     

相交集被合并的地方(注意集 a 和集 b 已合并;df也被合并了)。

有没有用 SQL 而不是存储过程的好方法。我知道我正在寻找一种联合查找程序。

【问题讨论】:

  • 可以获得多个交集吗? a + b + d?
  • @McNets,是的,这是必需的。
  • 如果您有行 (d, 9)、(e,10) 和 (d,11) - 您会查找 {9,11} 和 {10} 还是 {9,10 ,11} ?..
  • @VaoTsun,我编辑了问题以详细说明这些案例
  • 我的解决方案对你有用吗?..

标签: postgresql union-find


【解决方案1】:

准备:

so=> create table so75(set_id text, record_id int);
CREATE TABLE
so=> copy so75 from stdin;
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself.
>> ^CERROR:  COPY from stdin failed: canceled by user
CONTEXT:  COPY so75, line 1
so=> copy so75 from stdin delimiter '|';
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself.
>>      a |         1
 a |         2
 a |         3
 b |         2
 b |         4
 b |         5
 c |         6
 c |         7
 d |         9
 d |        11
 e |        10
 f |        11
 f |        12   
>> >> >> >> >> >> >>
>> \.
COPY 14

问:

so=> with keys as (
  with a as (
    select *,count(1) over (partition by record_id) c, array_agg(set_id) over(partition by record_id) cc
    from so75
  )
  select set_id, cc
  from a where c > 1
)
select distinct array_agg(distinct record_id)
from so75
left outer join keys on keys.set_id = so75.set_id
group by case when array_length(cc,1) > 1 then cc::text else so75.set_id end;
  array_agg
-------------
 {6,7}
 {10}
 {1,2,3,4,5}
 {9,11,12}
(4 rows)

【讨论】:

  • 我注意到重复项(缺少不同)和带有额外 set_id 的错误(在 group by 中缺少大小写)并修复了它 - 检查新代码是否也不起作用?...因为它在我的机器上起作用跨度>
  • dbfiddle.uk/… 抱歉,我不擅长小提琴。 {6,7} {1,3} {2,4,5}错了吗?..
  • rextester.com/WCDX49467 抱歉 - 我必须错过一些东西:('a',2),('a',4),('b',2),('b',4),('b',5),('c',6),('c',7),('d',1),('d',3),所以 a,b: {2,4,5} 和 c:6,7 和 d:1,3 - 对吧?..
  • 啊!我没有看到 - 我完全误解了这项任务!相交 - 你的意思是 2 包含在从 1 到 3 的数组中!我认为相交 - 共同的价值观!所以我解决了不同的任务:)
  • 是的,就是这样。
猜你喜欢
  • 2018-12-09
  • 1970-01-01
  • 1970-01-01
  • 2015-07-16
  • 2020-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多