1. 题目
# 写出一个sql语句查询在2025-10-15以后,
# 同一个用户下单2个以及2个以上状态为购买成功的
# C++课程或Java课程或Python课程的订单id,是否拼团以及客户端名字信息,
# 最后一列如果是非拼团订单,则显示对应客户端名字,
# 如果是拼团订单,则显示NULL,并且按照order_info的id升序排序
- 两张表
- 所需查询结果
2. 解题
思路:
1、所需结果有三个字段(列),有两个来自第一张表格,还有一个字段来自第二张表,很明显主要考察表连接。
那么就需要确定使用 INNER JOIN
还是 LEFT JOIN
,因为在进行行过滤(WHERE)之前我们是需要一个拥有完整id的表格
的,所以需要使用 LEFT JOIN
,保留所有的 id。
(题目中也特别说明了”拼团不统计客户端,所以client_id所以为0“,即表格 order_info
中的client_id
包含了client表格
中没有的id值
:0
)
2、看完了列,再来看如何进行行过滤。
结果需要的是满足一些列条件下的id
,以及其所附带的is_group_buy
和client_name
两个字段信息,所以需要对id
进行分组(后来想,其实id都是不重复的,因此不需要group by 操作,但是加上也不会报错)
这里条件中有一个【同一个用户下单2个以及2个以上】的要求,这个要求需要group by 的分组(或者窗口函数的分区)操作,需要将这部分代码放到子查询中。
前者可以使用IN操作在外表WHERE
中直接使用子查询,用于单独限定id;后者可以在FROM子查询
中使用窗口函数创造出一个新的字段(用户下单数量),再使用外层表格的SELECT进行取值。
(注意理解这里体现了两类子查询的方法:① 用于WHERE
中 ② 用于FROM
后面)
2.1 方法一:子查询
子查询的方法虽然理解起来非常自然和顺畅,但是写起来相对要复杂,且容易出错。(更推荐后面的窗口函数方法)
比如一些行限制条件要在外层表格和子查询中要”重复“使用,因为这里的子查询仅仅是对user_id
进行单独限制。
# 子查询方法
SELECT o.id,
o.is_group_buy,
c.name client_name
FROM order_info o
LEFT