语法
简单CASE表达式(比较固定值)
CASE 列名
WHEN 值1 THEN 结果1
WHEN 值2 THEN 结果2
ELSE 默认结果
END
搜索式CASE表达式(可以使用复杂条件)
CASE
WHEN 条件1 THEN 结果1
WHEN 条件2 THEN 结果2
ELSE 默认结果
END
举例说明
Id | name | score |
---|---|---|
1 | Alice | 95 |
2 | Bob | 82 |
3 | Charlie | 73 |
4 | David | 60 |
5 | Eva | 45 |
上面是学生的成绩表,现在需要我们给学生的成绩分级:
-- AS grade 是给 "CASE WHEN score >= 90 THEN 'A' ......ELSE 'F' END" 这一列去别名(grade)
-- WHEN score >= 90 THEN 'A': 当score >= 90,那么 grade=A
-- ELSE 'F': 其他情况, grade=F
SELECT
name,
score,
CASE
WHEN score >= 90 THEN 'A'
WHEN score >= 80 THEN 'B'
WHEN score >= 70 THEN 'C'
WHEN score >= 60 THEN 'D'
ELSE 'F'
END AS grade
FROM students;
最后的结果如下:
name | score | grade |
---|---|---|
Alice | 95 | A |
Bob | 82 | B |
Charlie | 73 | C |
David | 60 | D |
Eva | 45 | F |
MySQL中CASE表达式的用法
1. 创建测试数据库和表
-- 创建数据库
CREATE DATABASE case_demo;
USE case_demo;
-- 创建产品表
CREATE TABLE products (
product_id INT PRIMARY KEY AUTO_INCREMENT,
product_name VARCHAR(50),
price DECIMAL(10,2),
stock_quantity INT
);
-- 创建员工表
CREATE TABLE employees (
employee_id INT PRIMARY KEY AUTO_INCREMENT,
employee_name VARCHAR(50),
department_id INT,
salary DECIMAL(10,2)
);
-- 创建订单表
CREATE TABLE orders (
order_id INT PRIMARY KEY AUTO_INCREMENT,
customer_id INT,
customer_type VARCHAR(10),
order_date DATE,
amount DECIMAL(10,2)
);
-- 创建任务表
CREATE TABLE tasks (
task_id INT PRIMARY KEY AUTO_INCREMENT,
task_name VARCHAR(50),
priority VARCHAR(10),
due_date DATE
);
-- 创建用户表
CREATE TABLE users (
user_id INT PRIMARY KEY AUTO_INCREMENT,
user_name VARCHAR(50),
age INT
);
-- 创建学生成绩表
CREATE TABLE student_records (
student_id INT PRIMARY KEY AUTO_INCREMENT,
student_name VARCHAR(50),
score INT,
attendance_rate DECIMAL(3,2)
);
-- 创建订单详情表
CREATE TABLE order_details (
detail_id INT PRIMARY KEY AUTO_INCREMENT,
order_id INT,
product_id INT,
quantity INT,
order_date DATE
);
2. 插入测试数据
-- 产品数据
INSERT INTO products (product_name, price, stock_quantity) VALUES
('iPhone 14', 6999.00, 50),
('小米电视', 3299.00, 120),
('华为笔记本', 5999.00, 30),
('普通鼠标', 59.00, 200),
('机械键盘', 299.00, 80);
-- 员工数据
INSERT INTO employees (employee_name, department_id, salary) VALUES
('张三', 1, 15000.00),
('李四', 2, 12000.00),
('王五', 3, 18000.00),
('赵六', 1, 16000.00),
('钱七', 4, 10000.00);
-- 订单数据
INSERT INTO orders (customer_id, customer_type, order_date, amount) VALUES
(101, 'VIP', '2023-05-15', 2999.00),
(102, '普通', '2023-06-20', 1599.00),
(103, 'VIP', '2023-07-01', 899.00),
(104, '普通', '2023-07-10', 599.00);
-- 任务数据
INSERT INTO tasks (task_name, priority, due_date) VALUES
('完成项目提案', '高', '2023-08-15'),
('更新用户手册', '中', '2023-08-20'),
('修复登录BUG', '高', '2023-08-10'),
('优化数据库', '低', '2023-08-30');
-- 用户数据
INSERT INTO users (user_name, age) VALUES
('用户A', 18),
('用户B', 25),
('用户C', 32),
('用户D', 22),
('用户E', 45),
('用户F', NULL);
-- 学生成绩数据
INSERT INTO student_records (student_name, score, attendance_rate) VALUES
('学生1', 95, 0.98),
('学生2', 85, 0.92),
('学生3', 88, 0.85),
('学生4', 72, 0.95),
('学生5', 65, 0.75);
-- 订单详情数据
INSERT INTO order_details (order_id, product_id, quantity, order_date) VALUES
(1, 1, 1, '2022-11-15'),
(1, 3, 2, '2023-01-15'),
(2, 2, 1, '2022-11-20'),
(3, 4, 5, '2023-02-01'),
(4, 5, 3, '2022-12-10'),
(4, 1, 1, '2023-03-05');
示例1:基础分类用法
SELECT
product_name,
price,
CASE
WHEN price < 50 THEN '低价商品'
WHEN price BETWEEN 50 AND 200 THEN '中端商品'
WHEN price > 200 THEN '高端商品'
ELSE '未定价'
END AS price_category
FROM products;
结果:
+--------------+---------+---------------+
| product_name | price | price_category |
+--------------+---------+---------------+
| iPhone 14 | 6999.00 | 高端商品 |
| 小米电视 | 3299.00 | 高端商品 |
| 华为笔记本 | 5999.00 | 高端商品 |
| 普通鼠标 | 59.00 | 中端商品 |
| 机械键盘 | 299.00 | 高端商品 |
+--------------+---------+---------------+
示例2:简单CASE形式
SELECT
employee_name,
CASE department_id
WHEN 1 THEN '研发部'
WHEN 2 THEN '市场部'
WHEN 3 THEN '财务部'
ELSE '其他部门'
END AS department_name
FROM employees;
结果:
+--------------+----------------+
| employee_name | department_name |
+--------------+----------------+
| 张三 | 研发部 |
| 李四 | 市场部 |
| 王五 | 财务部 |
| 赵六 | 研发部 |
| 钱七 | 其他部门 |
+--------------+----------------+
示例3:在WHERE子句中使用
-- DATE_SUB('2023-07-20', INTERVAL 30 DAY) 是 MySQL 的日期函数,用于从指定日期 '2023-07-20' 减去 30 天。
-- '2023-07-20':起始日期。
-- INTERVAL 30 DAY:表示 30 天的时间间隔。
-- DATE_SUB:表示“日期减去间隔”。
-- 这个表达式的结果是 `2023-06-20`。
SELECT *
FROM orders
WHERE
CASE
WHEN customer_type = 'VIP' THEN order_date > DATE_SUB('2023-07-20', INTERVAL 30 DAY)
ELSE order_date > DATE_SUB('2023-06-30', INTERVAL 7 DAY)
END;
-- 如果customer_type = 'VIP',那么SQL就会变成
SELECT *
FROM orders
WHERE order_date > '2023-06-20'
结果:
+---------+-------------+---------------+------------+---------+
| order_id | customer_id | customer_type | order_date | amount |
+---------+-------------+---------------+------------+---------+
| 3 | 103 | VIP | 2023-07-01 | 899.00 |
| 4 | 104 | 普通 | 2023-07-10 | 599.00 |
+---------+-------------+---------------+------------+---------+
示例4:在ORDER BY中使用
SELECT *
FROM tasks
ORDER BY
CASE priority
WHEN '高' THEN 1
WHEN '中' THEN 2
WHEN '低' THEN 3
ELSE 4
END;
结果:
+---------+-----------------+----------+------------+
| task_id | task_name | priority | due_date |
+---------+-----------------+----------+------------+
| 1 | 完成项目提案 | 高 | 2023-08-15 |
| 3 | 修复登录BUG | 高 | 2023-08-10 |
| 2 | 更新用户手册 | 中 | 2023-08-20 |
| 4 | 优化数据库 | 低 | 2023-08-30 |
+---------+-----------------+----------+------------+
示例5:在UPDATE语句中使用
UPDATE products
SET price =
CASE
WHEN stock_quantity > 100 THEN price * 0.9 -- 库存多的打9折
WHEN stock_quantity BETWEEN 50 AND 100 THEN price * 0.95 -- 中等库存打95折
ELSE price * 1.05 -- 库存少的涨价5%
END;
SELECT product_name, price FROM products;
结果:
+--------------+---------+
| product_name | price |
+--------------+---------+
| iPhone 14 | 6649.05 |
| 小米电视 | 2969.10 |
| 华为笔记本 | 6298.95 |
| 普通鼠标 | 53.10 |
| 机械键盘 | 284.05 |
+--------------+---------+
示例6:在GROUP BY分组统计中使用
SELECT
CASE
WHEN age < 20 THEN '20岁以下'
WHEN age BETWEEN 20 AND 30 THEN '20-30岁'
WHEN age > 30 THEN '30岁以上'
ELSE '未知年龄'
END AS age_group,
COUNT(*) AS user_count
FROM users
GROUP BY age_group;
结果:
+------------+------------+
| age_group | user_count |
+------------+------------+
| 20岁以下 | 1 |
| 20-30岁 | 2 |
| 30岁以上 | 2 |
| 未知年龄 | 1 |
+------------+------------+
-- 可以先这么理解:先不统计数量
SELECT
CASE
WHEN age < 20 THEN '20岁以下'
WHEN age BETWEEN 20 AND 30 THEN '20-30岁'
WHEN age > 30 THEN '30岁以上'
ELSE '未知年龄'
END AS age_group
FROM users
结果:
+------------+
| age_group |
+------------+
| 20岁以下 |
| 20-30岁 |
| 30岁以上 |
| 20-30岁 |
| 30岁以上 |
| 未知年龄 |
+------------
示例7:嵌套CASE表达式
SELECT
student_name,
score,
CASE
WHEN score >= 90 THEN 'A'
WHEN score >= 80 THEN
CASE
WHEN attendance_rate > 0.9 THEN 'B+'
ELSE 'B'
END
WHEN score >= 70 THEN 'C'
ELSE 'F'
END AS grade
FROM student_records;
结果:
+--------------+-------+-------+
| student_name | score | grade |
+--------------+-------+-------+
| 学生1 | 95 | A |
| 学生2 | 85 | B+ |
| 学生3 | 88 | B |
| 学生4 | 72 | C |
| 学生5 | 65 | F |
+--------------+-------+-------+
示例8:与聚合函数结合使用
SELECT
product_id,
SUM(CASE WHEN order_date >= '2023-01-01' THEN quantity ELSE 0 END) AS qty_2023,
SUM(CASE WHEN order_date >= '2022-01-01' AND order_date < '2023-01-01' THEN quantity ELSE 0 END) AS qty_2022
FROM order_details
GROUP BY product_id;
结果:
+------------+-----------+-----------+
| product_id | qty_2023 | qty_2022 |
+------------+-----------+-----------+
| 1 | 1 | 1 |
| 2 | 0 | 1 |
| 3 | 2 | 0 |
| 4 | 5 | 0 |
| 5 | 0 | 3 |
+------------+-----------+-----------+
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1909773034@qq.com