我有一个看起来像这样的表:
station node group
13859160 13195576 high
13859160 42502030 low
13859165 42283197 low
13859165 42283198 high
13859166 13190800 low
13859166 13190801 low
13859166 13195587 high
可以使用以下语句创建:
CREATE TABLE nodes
("station" int, "node" int, "group" varchar(6))
;
并填写了这句话:
insert into nodes values (13859160, 13195576, 'high');
insert into nodes values (13859160, 42502030, 'low');
insert into nodes values (13859165, 42283197, 'low');
insert into nodes values (13859165, 42283198, 'high');
insert into nodes values (13859166, 13190800, 'low');
insert into nodes values (13859166, 13190801, 'low');
insert into nodes values (13859166, 13195587, 'high');
我想查询此表,以便高和低成为列,因此结果如下所示:
Station high low
13859160 13195576 42502030
13859165 42283198 42283197
13859166 13195587 13190801
13859166 13195587 13190800
如果那里没有多个“低”行的电台,那就很容易了,我可以做这样的事情来获得高点和低点:
select
"station",
case when "group" = 'high' then "node" end as high,
case when "group" = 'low' then "node" end as low
from "NODES";
导致:
然后使用聚合函数获取结果,如:
select
"station",
max(case when "group" = 'high' then "node" end) as high,
max(case when "group" = 'low' then "node" end) as low
from "NODES"
group by "station";
这导致:
但是,当1个startion有多个“low”enties时,我需要为每个低项创建一行,该行应该在两行中包含该站的相同“高”条目。
知道怎么做到这一点?
答案 0 :(得分:0)
您可以使用条件聚合执行此操作。
select * from (
select
"station",
max(case when "group" = 'high' then "node" end) over(partition by "station") as high,
case when "group" = 'low' then "node" end as low
from nodes
) n
where low is not null
答案 1 :(得分:0)
首先,我可能会建议listagg()
进行聚合查询:
select "station",
listagg(case when "group" = 'high' then "node" end) as high,
listagg(case when "group" = 'low' then "node" end) as low
from "NODES"
group by "station";
要为单个工作站获取多行,您可以使用row_number()
:
select "station",
max(case when "group" = 'high' then "node" end) as high,
max(case when "group" = 'low' then "node" end) as low
from (select n.*,
row_number() over (partition by "station", "group" order by "node") as seqnum
from "NODES" n
) n
group by "station", seqnum;
最后,如果您想要重复上一个最大值:
select "station",
coalesce(max(case when "group" = 'high' then "node" end),
max(max(case when "group" = 'high' then "node" end)) over (partition by "station)
) as high,
max(case when "group" = 'low' then "node" end) as low
from (select n.*,
row_number() over (partition by "station", "group" order by "node") as seqnum
from "NODES"
) n
group by "station", seqnum;