我试图弄清楚如何用SQL做到这一点。我在客户表中有一个带有以下各列的表-(Customer_Id,性别,生日)。问题是-我需要找到Gender的最早和最新出生的人。本质上是不同组的最小值和最大值。
123 M 2017-07-05 00:00:00.000
345 M 2016-08-01 00:00:00.000
555 F 2012-01-09 00:00:00.000
567 F 2015-02-07 00:00:00.000
789 F 2013-01-02 00:00:00.000
111 F 2000-01-01 00:00:00.000
188 M 2008-09-01 00:00:00.000
结果集应如下所示
188 M 2008-09-01 00:00:00.000
123 M 2017-07-05 00:00:00.000
111 F 2000-01-01 00:00:00.000
567 F 2015-02-07 00:00:00.000
我可以做4个UNION
并以这种方式找出答案,但这效率不高。
这是我想出的,但这也不起作用。如何在一个查询中同时为MAX组做到这一点?
select a.Customer_id, a.gender, b.min_birthday
from(
select gender, min(birthday) min_birthday
from Sales..Customer group by gender) b join Sales..Customer a on b.gender = a.gender
and b.min_birthday = a.birthday
答案 0 :(得分:1)
一种方法使用窗口函数:
select customer_id, gender, birthday
from (select c.*,
row_number() over (partition by gender order by birthday) as seqnum_asc,
row_number() over (partition by gender order by birthday desc) as seqnum_desc
from customer c
) c
where 1 in (seqnum_asc, seqnum_desc);
如果要联系,请使用rank()
代替row_number()
。
也就是说,使用(gender, birthday)
和(gender, birthday desc)
上的索引(如果优化程序有所改进,可能不再需要两个索引),union all
方法应该表现得很好:>
select c.*
from ((select top (1) c.*
from customer c
where gender = 'M'
order by birthday
) union all
(select top (1) c.*
from customer c
where gender = 'F'
order by birthday
) union all
(select top (1) c.*
from customer c
where gender = 'M'
order by birthday desc
) union all
(select top (1) c.*
from customer c
where gender = 'F'
order by birthday desc
)
) c;
答案 1 :(得分:0)
实际上一个UNION ALL
就足够了:)
select gender, min(birthday) birthday, 'MIN' Aggregate
from Sales..Customer group by gender
union all
select gender, max(birthday), 'MAX'
from Sales..Customer group by gender
但是更好的痤疮应该是:
select gender, min(birthday), max(birthday)
from Sales..Customer group by gender
但是结果将与期望的略有不同。
答案 2 :(得分:0)
您可以使用“不存在”来做到这一点:
select c.* from Customer c
where not exists (
select 1 from Customer
where gender = c.gender and birthday < c.birthday
) or not exists (
select 1 from Customer
where gender = c.gender and birthday > c.birthday
)
order by c.gender, c.birthday
请参见demo。
结果:
> id | gender | birthday
> :-- | :----- | :------------------
> 111 | F | 01/01/2000 00:00:00
> 567 | F | 07/02/2015 00:00:00
> 188 | M | 01/09/2008 00:00:00
> 123 | M | 05/07/2017 00:00:00