每个组的最高值

4

由于这里很难展示我的实际表格和数据,所以我将用一个样例表格和数据描述我的问题:

create table foo(id int,x_part int,y_part int,out_id int,out_idx text);

insert into foo values (1,2,3,55,'BAK'),(2,3,4,77,'ZAK'),(3,4,8,55,'RGT'),(9,10,15,77,'UIT'),
                       (3,4,8,11,'UTL'),(3,4,8,65,'MAQ'),(3,4,8,77,'YTU');

以下是表格 foo
id x_part y_part out_id out_idx 
-- ------ ------ ------ ------- 
3  4      8      11     UTL     
3  4      8      55     RGT     
1  2      3      55     BAK     
3  4      8      65     MAQ     
9  10     15     77     UIT     
2  3      4      77     ZAK     
3  4      8      77     YTU     

我需要通过排序每个out_id的最高id来选择所有字段。
期望输出:
id x_part y_part out_id out_idx 
-- ------ ------ ------ ------- 
3  4      8      11     UTL     
3  4      8      55     RGT     
3  4      8      65     MAQ     
9  10     15     77     UIT     

使用PostgreSQL。

最快的解决方案取决于基数、数据分布以及是否有一个包含所有不同“out_id”的表。详情请见:https://dev59.com/Wm865IYBdhLWcg3wduaH#7630564 - Erwin Brandstetter
3个回答

4

Postgres特定解决方案(也是最快的):

select distinct on (out_id) *
from foo
order by out_id, id desc;

使用窗口函数的标准SQL解决方案(第二快)

select id, x_part, y_part, out_id, out_idx
from (
  select id, x_part, y_part, out_id, out_idx, 
         row_number() over (partition by out_id order by id desc) as rn
  from foo
) t
where rn = 1
order by id;

请注意,这两种解决方案仅返回每个id一次,即使有多个out_id值相同。如果您想要返回它们所有,请使用dense_rank()而不是row_number()

1
select * 
from foo 
where (id,out_id) in (
select max(id),out_id from foo group by out_id
) order by out_id

1

找到 max(val) := 找到记录中没有更大的 val

SELECT * 
FROM foo f
WHERE NOT EXISTS (
   SELECT 317
   FROM foo nx
   WHERE nx.out_id = f.out_id
   AND nx.id > f.id
   );

不错。where out_id > all (select .. ) 是另一种变体。 - user330315

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接