题目描述
我们有一个表:
order_info
:包含订单信息,包括订单IDid
、用户IDuser_id
、产品名称product_name
、订单状态status
、客户端IDclient_id
和订单日期date
。
目标是查询出在2025年10月15日之后,同一个用户下单2个及以上状态为“completed”的“C++”、“Java”或“Python”课程订单的用户ID、第一次和第二次购买成功的日期,以及购买成功的次数,并按用户ID升序排序。
知识点
- 条件过滤:使用
WHERE
子句筛选符合条件的记录。 - 窗口函数:使用
ROW_NUMBER
和COUNT
窗口函数计算每个用户的订单排名和总订单数量。 - 聚合函数:使用
MIN
和MAX
函数获取每个用户的第一次和第二次购买成功日期。 - 分组:使用
GROUP BY
子句按用户ID分组。 - 排序:使用
ORDER BY
子句按用户ID升序排列结果。
关键问题分析
1. 筛选符合条件的订单
我们需要筛选出状态为“completed”的订单,产品名称为“C++”、“Java”或“Python”,并且订单日期在2025年10月15日之后:
where status = 'completed' and product_name in ('C++','Java','Python') and date > '2025-10-15'
2. 计算每个用户的订单排名和总订单数量
我们使用ROW_NUMBER
和COUNT
窗口函数计算每个用户的订单排名和总订单数量:
row_number() over(partition by user_id order by date asc) as rn,
count(*) over(partition by user_id) as cnt
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY date ASC) AS rn
: 计算每个用户的订单排名。COUNT(*) OVER (PARTITION BY user_id) AS cnt
: 计算每个用户的总订单数量。
3. 筛选订单数量大于等于2的用户
我们通过WHERE
子句筛选出订单数量大于等于2的用户,并且只考虑前两次购买:
where cnt >= 2 and rn in (1,2)
4. 获取第一次和第二次购买成功的日期
在筛选出前两次购买之后,我们可以直接使用MIN
和MAX
函数获取每个用户的第一次和第二次购买成功日期:
min(date) as first_buy_date,
max(date) as second_buy_date
5. 分组和排序输出
我们按用户ID分组,并按用户ID升序排列输出结果:
group by user_id
order by user_id
完整代码
select user_id, min(date) as first_buy_date, max(date) as second_buy_date, cnt
from (
select
user_id, date,
row_number() over(partition by user_id order by date asc) as rn,
count(*) over(partition by user_id) as cnt
from order_info
where status = 'completed' and product_name in ('C++','Java','Python') and date > '2025-10-15'
) sub
where cnt >= 2 and rn in (1,2)
group by user_id
order by user_id;