题目描述

我们有两个表:

  • order_info:包含订单信息,包括订单ID id、用户ID user_id、产品名称 product_name、订单状态 status、客户端ID client_id、订单日期 date 和是否拼团 is_group_buy
  • client:包含客户端信息,包括客户端ID id 和客户端名称 name

目标是查询出在2025年10月15日之后,同一个用户下单2个及以上状态为“completed”的“C++”、“Java”或“Python”课程订单的订单ID、是否拼团以及客户端名称信息,并按订单ID升序排序。

知识点

  • 条件过滤:使用WHERE子句筛选符合条件的记录。
  • 窗口函数:使用COUNT窗口函数计算每个用户的订单数量。
  • 连接操作:使用LEFT JOIN连接订单信息表和客户端表。
  • 排序:使用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. 计算每个用户的订单数量

我们使用COUNT窗口函数计算每个用户的订单数量:

count(*) over(partition by user_id) as cnt
  • COUNT(*) OVER (PARTITION BY user_id) AS cnt: 计算每个用户的订单数量。

3. 筛选订单数量大于等于2的用户

我们通过WHERE子句筛选出订单数量大于等于2的用户:

where sub.cnt >= 2

4. 连接客户端信息

我们使用LEFT JOIN连接订单信息表和客户端表,以获取客户端名称:

left join client c on sub.client_id = c.id
  • LEFT JOIN client c ON sub.client_id = c.id: 连接客户端信息,拼团的也显示即要求左连接。。

5. 排序输出

我们按订单ID升序排列输出结果:

order by sub.id

完整代码

select sub.id, sub.is_group_buy, 
       case when sub.is_group_buy = 'Yes' then NULL else c.name end as client_name
from (
    select id, is_group_buy, client_id,
           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
left join client c on sub.client_id = c.id
where sub.cnt >= 2
order by sub.id;