题目描述
我们有两个表:
order_info
:包含订单信息,包括订单IDid
、用户IDuser_id
、产品名称product_name
、订单状态status
、客户端IDclient_id
、订单日期date
和是否拼团is_group_buy
。client
:包含客户端信息,包括客户端IDid
和客户端名称name
。
目标是查询出在2025年10月15日之后,同一个用户下单2个及以上状态为“completed”的“C++”、“Java”或“Python”课程订单的来源信息,并按来源升序排序。
知识点
- 条件过滤:使用
WHERE
子句筛选符合条件的记录。 - 窗口函数:使用
COUNT
窗口函数计算每个用户的订单数量。 - 连接操作:使用
LEFT JOIN
连接订单信息表和客户端表。 - 条件判断:使用
CASE
语句处理拼团订单的来源显示。 - 分组和排序:使用
GROUP BY
和ORDER BY
子句进行分组和排序。
关键问题分析
1. 筛选符合条件的订单
我们需要筛选出状态为“completed”的订单,产品名称为“C++”、“Java”或“Python”,并且订单日期在2025年10月15日之后:
where status = 'completed' and product_name in ('C++','Java','Python') and date > '2025-10-15'
2. 计算每个用户的订单数量
我们使用COUNT
窗口函数计算每个用户的订单数量:
count(*) over(partition by o.user_id) as cn
COUNT(*) OVER (PARTITION BY o.user_id) AS cn
: 计算每个用户的订单数量。
3. 筛选订单数量大于等于2的用户
我们通过WHERE
子句筛选出订单数量大于等于2的用户:
where sub.cn >= 2
4. 连接客户端信息
我们使用LEFT JOIN
连接订单信息表和客户端表,以获取客户端名称:
left join client c on o.client_id = c.id
LEFT JOIN client c ON o.client_id = c.id
: 连接客户端信息。
5. 处理拼团订单的来源显示
我们使用CASE
语句处理拼团订单的来源显示:
select case when name is null then 'GroupBuy' else name end as source, count(*) as cnt
CASE WHEN name IS NULL THEN 'GroupBuy' ELSE name END AS source
: 处理拼团订单的来源显示。
6. 分组和排序输出
我们按来源分组,并按来源升序排列输出结果:
group by name
order by source
完整代码
select case when name is null then 'GroupBuy' else name end as source, count(*) as cnt
from (
select o.id, c.name,
count(*) over(partition by o.user_id) as cn
from order_info o
left join client c on o.client_id = c.id
where status = 'completed' and product_name in ('C++','Java','Python') and date > '2025-10-15'
) sub
where sub.cn >= 2
group by name
order by source;