Skip to content

sql-case

CASE 表达式是 SQL 处理 if/then/else 逻辑的方式。它允许你评估一系列条件并返回多个可能结果表达式中的一个。它不像过程式语言中的 IF 语句那样控制执行流程;相反,它是一个返回值的表达式。

这使得它在单个 SQL 语句中创建派生列、自定义排序逻辑和条件更新方面具有极大的灵活性。

CASE 表达式有两种形式:

这种形式将一个表达式与一组特定值进行比较。

CASE input_expression
WHEN value1 THEN result1
WHEN value2 THEN result2
...
ELSE else_result
END

这种形式评估一组独立的布尔条件。

CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
...
ELSE else_result
END

注意:CASE 语句按顺序处理条件,并在遇到第一个满足的条件时停止。可选的 ELSE 子句处理没有条件满足的情况;如果省略,则返回 NULL。

让我们使用 CUSTOMERS 表根据客户的 SALARY(薪资)将其分为不同的等级。

CREATE TABLE CUSTOMERS(
ID INT PRIMARY KEY, NAME VARCHAR(20) NOT NULL, AGE INT NOT NULL,
ADDRESS CHAR(25), SALARY DECIMAL(18, 2)
);
INSERT INTO CUSTOMERS VALUES
(1, 'Ramesh', 32, 'Ahmedabad', 2000.00),
(2, 'Khilan', 25, 'Delhi', 1500.00),
(3, 'Kaushik', 23, 'Kota', 2000.00),
(4, 'Chaitali', 25, 'Mumbai', 6500.00),
(5, 'Hardik', 27, 'Bhopal', 8500.00),
(6, 'Komal', 22, 'Hyderabad', 4500.00),
(7, 'Muffy', 24, 'Indore', 10000.00);

此查询使用搜索 CASE 表达式来创建新的 CustomerTier(客户等级)列。

SELECT NAME, SALARY,
CASE
WHEN SALARY >= 9000 THEN 'Platinum'
WHEN SALARY >= 6000 THEN 'Gold'
WHEN SALARY >= 3000 THEN 'Silver'
ELSE 'Bronze'
END AS CustomerTier
FROM CUSTOMERS;
姓名薪资客户等级
Ramesh2000.00Bronze
Khilan1500.00Bronze
Kaushik2000.00Bronze
Chaitali6500.00Gold
Hardik8500.00Gold
Komal4500.00Silver
Muffy10000.00Platinum

CASE 可以创建复杂的排序规则。例如,让我们按地址对客户进行排序,但确保所有来自“孟买”的客户排在前面。

SELECT NAME, ADDRESS, SALARY
FROM CUSTOMERS
ORDER BY
CASE
WHEN ADDRESS = 'Mumbai' THEN 1
ELSE 2
END, -- 主要排序键
NAME ASC; -- 次要排序键

你还可以根据 CASE 表达式的结果进行分组。这对于创建自定义聚合桶很有用。

SELECT
CASE
WHEN SALARY < 5000 THEN 'Entry Level'
WHEN SALARY >= 5000 AND SALARY < 9000 THEN 'Mid Level'
ELSE 'Senior Level'
END AS SalaryBracket,
COUNT(ID) AS NumberOfCustomers,
AVG(SALARY) AS AverageSalary
FROM CUSTOMERS
GROUP BY SalaryBracket;
薪资区间客户数量平均薪资
Entry Level42500.00
Mid Level27500.00
Senior Level110000.00

CASE 非常适合条件更新。让我们根据当前薪资进行加薪。

UPDATE CUSTOMERS
SET SALARY =
CASE
WHEN SALARY < 2000 THEN SALARY * 1.15 -- 加薪 15%
WHEN SALARY < 5000 THEN SALARY * 1.10 -- 加薪 10%
ELSE SALARY * 1.05 -- 加薪 5%
END
WHERE ID > 0; -- 在 UPDATE 语句中始终添加 WHERE 子句是个好习惯

运行更新后,你可以查询数据以查看新的薪资。

SELECT NAME, SALARY FROM CUSTOMERS;
  • 数据类型一致性:CASE 语句中所有的 THEN 和 ELSE 表达式必须返回兼容的数据类型。你不能在一个 THEN 中返回数字,而在另一个 THEN 中返回字符串。
  • 不要忘记 ELSE:省略 ELSE 子句会导致不满足任何 WHEN 条件的行返回 NULL。这可能是有意的,但通常是错误的来源。请明确指定。
  • 顺序很重要:WHEN 条件按其书写的顺序进行评估。第一个评估为真的条件决定结果,随后的条件将被忽略。
  • NULL 处理:与 NULL 的比较(例如,WHEN my_column = NULL)很棘手。检查 NULL 的正确方法是 WHEN my_column IS NULL。