我有一个包含三列的长表:
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
非常感谢帮助!
答案 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以有序的方式检索行,并在应用程序中处理/过滤它。