在 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
之外是相同的)
我有一个很长的 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
之外是相同的)