MySQL实战解析:一篇搞懂CASE WHEN、JOIN、IN子查询等核心用法!

在日常的数据分析或产品运营工作中,**如何用 SQL 快速获取“某城市女性用户数”“每位用户最近一笔订单”**这些业务常见问题,是一项非常核心的能力。

这篇文章通过一个模拟用户订单数据的表结构,用真实业务语境,带你掌握以下关键 SQL 技能:

  • JOIN连接的实际用途

  • GROUP BY + 聚合函数统计

  • DISTINCTSUM 的联动逻辑

  • IN + 多字段子查询的精妙组合

  • 最重头戏:CASE WHEN 条件聚合与标签划分

首先,我们准备两个过会用于操作的数据表:

一、建表+数据准备(模拟订单业务)

CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,    #自增主键
  name VARCHAR(100),                    #姓名,不许为空
  age INT,                             #年龄
  gender ENUM('M', 'F'),                #性别,只能是“M”或“F”
  city VARCHAR(100)                   #城市 
);

CREATE TABLE orders (
  id INT PRIMARY KEY AUTO_INCREMENT,    #自增主键
  user_id INT,                            #用户id 整数类型
  product_name VARCHAR(100),             #商品名称
  amount DECIMAL(10,2),                 #消费金额 保留两位小数
  order_date DATE                        #消费日期
);

知识梳理:

  1. 创建表格的语法结构:
    CREATE TABLE 表名 (
        列名1 数据类型 [约束],
        列名2 数据类型 [约束],
        ...
    );
    

    约束条件:由“数据类型+列约束”组成,常见的数据类型有:INT:(整数)、varchar(n) :字符串,最大长度为n、DATE :日期(YYYY-MM-DD)、decimal(m,n)  :小数类型,m表示数字的总位数(包括整数部分和小数部分),保留n位小数。

  2. 为了能够对之后的语句进行测试,先使用insert 语句 为以上创建的表格导入模拟数据信息:

INSERT INTO users (name, age, gender, city) VALUES
('Alice', 25, 'F', 'Beijing'),
('Bob', 34, 'M', 'Shanghai'),
('Cathy', 19, 'F', 'Beijing'),
('David', 45, 'M', 'Guangzhou'),
('Eva', 29, 'F', 'Shenzhen'),
('Frank', 52, 'M', 'Beijing'),
('Grace', 38, 'F', 'Shanghai');
INSERT INTO orders (user_id, product_name, amount, order_date) VALUES
(1, 'Phone',     499.99, '2024-12-01'),
(1, 'Headset',   89.90,  '2025-01-15'),
(2, 'Laptop',    1200.00, '2025-02-20'),
(3, 'Book',      59.00,  '2025-03-05'),
(4, 'Camera',    800.00, '2025-03-10'),
(4, 'Tripod',    120.00, '2025-03-11'),
(5, 'Phone Case',15.00,  '2025-04-01'),
(6, 'TV',        1500.00,'2025-05-01');

已经有了两个表格的数据信息,那么接下来就进行常见的业务问题的实战训练:

二、基础查询:

1.查询所有女性用户的姓名和所在城市。

涉及:SELECT 、WHERE

SELECT name, city FROM users WHERE gender = 'F';

知识梳理:

  1. SELECT 查询语句的基本语法结构:

简洁版:SELECT  [字段]  FROM  [表格名]  [条件]

详细版:(见下图)

这里的WHERE、GROUP BY、HAVING等条件在根据查询的需要时,按照以上的次序撰写代码。

2.查询所有订单中金额大于100的记录,并按金额降序排列。

涉及:WHEREORDER BY

SELECT * FROM orders 
WHERE amount > 100.00 
ORDER BY amount DESC;

 知识梳理:

  1. “ * ”  是代表所有的意思,这里的含义是筛选出orders表中所有满足条件的语句。
  2. WHERE 语句是对数据进行判断,满足条件的就会被筛选出来。
  3. ORDER BY amount DESC :指的是按照amount 用户消费金额降序排序,DESC是降序的意思,如果不写desc就是默认升序排序。

三、聚合与分组

3. 查询每个用户的总消费金额(显示用户姓名和总金额)。

涉及:JOINGROUP BYSUM

select name,sum(amount) from orders    #查询用户的名称及消费总金额
join users u on orders.user_id = u.id   #两个表格建立联系的“纽带”
group by name;   #以name字段分组

思路解析:

  1. 总消费金额:就需要将所有的消费数据汇总使用SUM函数
  2. 每个用户的总消费金额:要按照用户的姓名字段进行分组汇总消费金额。
  3. 用户名称与用户消费金额amount不在同一张表格上需要两张表连接进行查询。因此使用join 连接,on 加上两个表格建立联系的条件。

四、多表连接与子查询

4.查询从未下过订单的用户姓名。

涉及  LEFT JOIN、WHERE

select distinct name 
from  users u 
left join  orders on orders.user_id = u.id 
where user_id is null;

思路解析:

  1. 使用WHERE语句判断user_id为空的用户,说明他并没有下过订单。 

  2. distinct 指的是不重复的数据信息。这里指的是过滤掉多次下单的用户名称。

  3. 用户名与订单信息不在同一张表格上需要两张表连接进行查询。因此使用join 连接,on 加上两个表格建立联系的条件。

5.查询每位用户最近的一笔订单(金额和时间)

涉及 JOIN、WHERE、子查询、GROUP BY

SELECT u.name, o.amount, o.order_date
FROM orders o
JOIN users u ON o.user_id = u.id
WHERE (o.user_id, o.order_date) IN (
    SELECT (user_id, MAX(order_date)
    FROM orders
    GROUP BY user_id
);

思路解析:

用户名--那笔订单的金额--订单日期(是最近的一笔)(使用子查询进行)

  1. 子查询获取每个用户的 user_id + 最新 order_date

  2. 外层再通过 (user_id, order_date) 来匹配具体订单;

  3. 最终取出对应的金额和时间。

  4. 多字段匹配IN子查询中的(A,B)要与外层的(A,B)的顺序完全一致才可以进行比较。在这里也就是,(o.user_id, o.order_date) -->“外层” 与 (user_id, MAX(order_date) -->“内层”顺序相一致。

6. 查询所有用户的年龄段(<20为少年,20-40为青年,>40为中老年)及每个段位的人数

涉及CASE WHEN 、 COUNT、GROUP BY

SELECT
  CASE
    WHEN age < 20 THEN '少年'
    WHEN age BETWEEN 20 AND 40 THEN '青年'
    ELSE '中老年'
  END AS 年龄段,
  COUNT(*) AS 人数
FROM users
GROUP BY 年龄段;

思路解析:

这里具有多个情况需要进行判断,case when是sql语句中条件判断语句

  • 使用 CASE WHEN 为用户分类;case when的基本语法结构是:

SELECT
  CASE 
    WHEN 条件1 THEN 结果1
    WHEN 条件2 THEN 结果2
    ...
    ELSE 默认结果
  END AS 别名
FROM 表名;

在这道题目中,年龄区间就是判断的条件,而少年、青年、中老年就是判断后的结果。 

  • 配合 GROUP BY 对年龄段分组;

  • COUNT(*) 统计每组人数。

  • END AS 可以为查询结果的列命名。

总结:从业务视角理解 SQL,更高效也更精准

通过这篇文章,我们不仅掌握了常见的 SQL 语法,但代码永远只是工具,更重要的是:你能不能把一个业务问题,转化为一条可执行的SQL语句。更重要的是学会了如何围绕业务问题建构查询思路

对于SQL语言来说,最重要的是理解每个语句为何这么写、函数的逻辑含义以及结构。在查询时,首先可以思考一下,是否需要条件进行判断?是否需要根据哪些内容分组?是否有多个条件需要进行判断?欢迎评论区留言你遇到过的 SQL 难题,我们一起拆解!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值