在每个元组中使用不同数量的项目查找表中的元组

时间:2018-05-16 13:04:22

标签: sql h2 relational-division

我有一个包含三列的长表:

ID, Type, Plan No

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

在下面的源表中,第二个ID(183217760)有三种不同的关联类型(S39905028,S39905133,S39905242),其中包含三个不同的"计划编号" s。第一个ID(183217488)将不符合资格,因为"计划编号" 300缺少第二个" Type"。

因此该函数应返回类似

的内容
183217760   200, 300, 400
183218746   200, 300
183218747   200, 300
183219126   200, 300
etc.

进行连接不起作用,因为我不知道将合并多少行。源数据非常庞大,并且可能存在包含20个或更多项的元组。

这是源表:

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

非常感谢帮助!

2 个答案:

答案 0 :(得分:2)

我不知道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之外,它是相同的)

答案 1 :(得分:1)

使用程序算法可以更有效地解决这个问题。

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