我需要选择 n 个最高的人和 n 个最矮的人 人是男性。高度存储在名为“高度”的列中,性别存储在相应命名的列中(如 F 或 M)
我试过这样的事情
select name,height from people where gender = 'M' order by height asc limit 5
然后我想以某种方式将这个结果和同一行的结果按降序连接起来。
我也想知道你是否可以通过其他方式做到这一点。
我想象这个操作的结果是这样的
(身高数字是随机的,但左边的成对列应该包含最高的人,右边的成对列应该包含最短的)
我也试过这样的
(select name,height from people where gender = 'M' order by height desc limit 5) union (select name,height from people where gender = 'M' order by height asc limit 5) order by height asc
但我不喜欢这样的结果,因为您没有将 2 列分隔为最短和最高,而是全部在 1 列中,您需要从顶部手动计算 n 人数量以查看哪一个是最高。
我在 postgreSQL 中这样做
答案 0 :(得分:0)
假设两列没有重叠,您可以使用两个行号的技巧:
select max(name) filter (where seqnum_desc < seqnum_asc) as name_tall,
max(height) filter (where seqnum_desc < seqnum_asc) as height_tall,
max(name) filter (where seqnum_asc < seqnum_desc) as name_short,
max(height) filter (where seqnum_asc < seqnum_desc) as height_short
from (select p.*,
row_number() over (partition by gender order by height asc) as seqnum_asc,
row_number() over (partition by gender order by height desc) as seqnum_desc
from people p
where gender = 'M'
) p
where seqnum_asc <= 5 or seqnum_desc <= 5
group by least(seqnum_asc, seqnum_desc)
Here 是一个 db<>fiddle。
请注意:这应该适用于旧版本:
select max(case when seqnum_desc < seqnum_asc then name end) as name_tall,
max(case when seqnum_desc < seqnum_asc then height end ) as height_tall,
max(case when seqnum_asc < seqnum_desc then name end) as name_short,
max(case when seqnum_asc < seqnum_desc then height end) as height_short
from (select p.*,
row_number() over (partition by gender order by height asc) as seqnum_asc,
row_number() over (partition by gender order by height desc) as seqnum_desc
from people p
where gender = 'M'
) p
where seqnum_asc <= 5 or seqnum_desc <= 5
group by least(seqnum_asc, seqnum_desc)