对于group by时,select只能出现分组字段和聚集函数的结果,如何拿到其中任意一条记录的字段呐?可以配合SQL的语法,在外层套一个聚集函数在内if限定记录即可。


with view4base as(
select
user_id,`date`,
min(`date`) over(partition by user_id) first_buy_date,
lead(`date`,1) over(partition by user_id order by `date`) second_buy_date,
count(1) over(partition by user_id) cnt
from order_info
where `date` > '2025-10-15'
and product_name in('C++','Java','Python')
and `status` = 'completed'
)
select user_id,first_buy_date,second_buy_date,cnt
from view4base
where cnt > 1 and `date` = first_buy_date
order by user_id
/*
view中如果只拿第一次的日期该如何解决?
如何拿第2日期呐?
max() 配if + null,配合SQL语法,用max()也能拿到第二日期放在同一行。
*/
with view4base as(
select
user_id,`date`,
min(`date`) over(partition by user_id) first_buy_date
from order_info
where `date` > '2025-10-15'
and product_name in('C++','Java','Python')
and `status` = 'completed'
)
select
user_id,first_buy_date,
min(if(`date` = first_buy_date,null,`date`)) second_buy_date,
count(1) cnt
from view4base
group by user_id,first_buy_date
having count(1) > 1
order by user_id
# 如果要第三第四等等,可以这种if比较繁琐,可max() + if + rank()让max只从一条记录中筛选。
with view4base as(
select
user_id,`date`,
rank() over(partition by user_id order by `date`) rk
from order_info
where `date` > '2025-10-15'
and product_name in('C++','Java','Python')
and `status` = 'completed'
)
select
user_id,min(`date`) first_buy_date,
min(if(rk = 2,`date`,null)) second_buy_date,
count(1) cnt
from view4base
group by user_id
having count(1) > 1
order by user_id
1)想把SQL玩的6,就必须有抽象的能力,我重来没想过在聚集函数里加if,甚至对字段做运算,甚至多字段,其实这都是可以的,把聚集函数内层当一个集合,而给什么集合自己可以随意。
2)举一反三,那么窗口函数得到的排名值等各种值,其实也可以拿来当成运算,而不需要等到外层view。
[1] 牛客SQL篇