在 table 中查找每个元组具有不同项目数的元组

Finding tuples in table with varying number of items per tuple

我有一个很长的 table 三列:

ID, Type, Plan No

并且我试图找到 "ID"s,其中我具有与不同 "Plan No"s 关联的完全相同的 "Type"s 组合,但只有这些。

在源代码 table 中,第二个 ID (183217760) 具有三个不同的关联类型(S39905028、S39905133、S39905242)和三个不同的 "Plan No"。第一个 ID (183217488) 不合格,因为 "Plan No" 300 缺少第二个 "Type".

因此函数应该return类似于

183217760   200, 300, 400
183218746   200, 300
183218747   200, 300
183219126   200, 300
etc.

做join不行,因为不知道要合并多少行。源数据很大,可能有包含 20 个或更多项的元组。

这是来源table:

ID          Type        Plan No
183217488   S39905038   200
183217488   S39905133   200
183217488   S39905133   300
183217760   S39905028   200
183217760   S39905028   300
183217760   S39905028   400
183217760   S39905133   200
183217760   S39905133   300
183217760   S39905133   400
183217760   S39905242   200
183217760   S39905242   300
183217760   S39905242   400
183218106   S39905301   200
183218746   S39905028   200
183218746   S39905028   300
183218746   S39905133   200
183218746   S39905133   300
183218747   S39905028   200
183218747   S39905028   300
183218747   S39905133   200
183218747   S39905133   300
183219126   S39905028   200
183219126   S39905028   300
183219126   S39905133   200
183219126   S39905133   300
183219924   S39905028   200
183219924   S39905133   200
183219924   S39905133   300
183220269   B39910001   200
183220269   S39905012   200
183220269   S39905133   200
183220269   S39905301   200
183220271   B39910001   200
183220271   S39905012   200
183220271   S39905133   200
183220271   S39905301   200

非常感谢您的帮助!

使用过程算法解决这个问题会更有效。

即使我确定您可以使用 SQL 做到这一点,但尝试它会变得非常慢。您最好使用 SQL 以有序的方式检索行,并在您的应用程序中 process/filter 它。

我不知道 H2 的效率如何,但以下内容似乎适用于您的示例数据:

with plan_counter as (
  select id, type, count(distinct plan_no) as plan_count
  from plans
  group by id, type
), type_counter as (
  select id, plan_no, count(distinct type) as type_count
  from plans
  group by id, plan_no
), combined as (
  select pc.id, pc.type, tc.plan_no, pc.plan_count, tc.type_count
  from plan_counter pc
    join type_counter tc on tc.id = pc.id
)
select c1.id, group_concat(distinct c1.plan_no order by c1.plan_no separator ',') as plans
from combined c1
where not exists (select *
                  from combined c2
                  where c2.id = c1.id 
                    and c2.plan_count <> c2.type_count)  
group by c1.id
order by c1.id;

这是一个在线示例:http://rextester.com/WKT8701
(以上使用 Postgres,但除了使用 string_agg() 而不是 group_concat 之外是相同的)