SQL中的 CASE WHEN 是一个条件表达式,用于在查询中实现逻辑判断和分支处理。以下是其常用场景分析及示例:
一、基本语法
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
...
ELSE default_result
END
或简单表达式(比较固定值):
CASE column
WHEN value1 THEN result1
WHEN value2 THEN result2
ELSE default_result
END
二、常用场景分析
1. 数据分类与打标签
场景:将数值型字段转换为分类标签。
SELECT
order_id,
amount,
CASE
WHEN amount >= 1000 THEN '大额订单'
WHEN amount >= 500 THEN '中额订单'
ELSE '小额订单'
END AS order_type
FROM orders;
2. 数据标准化
场景:统一不同格式的数据。
SELECT
user_id,
CASE
WHEN country IN ('US', 'USA', 'United States') THEN '美国'
WHEN country = 'UK' THEN '英国'
ELSE country
END AS country_standard
FROM users;
3. 空值处理与默认值
场景:将NULL替换为默认值。
SELECT
product_name,
CASE
WHEN stock IS NULL THEN 0
ELSE stock
END AS stock_count
FROM products;
4. 条件聚合统计
场景:按条件分组计数或求和。
SELECT
department_id,
COUNT(*) AS total_employees,
SUM(CASE WHEN salary >= 10000 THEN 1 ELSE 0 END) AS high_salary_count,
SUM(CASE WHEN hire_date >= '2023-01-01' THEN 1 ELSE 0 END) AS new_hires
FROM employees
GROUP BY department_id;
5. 行列转换
场景:将行数据转为列(类似透视表)。
SELECT
product_category,
SUM(CASE WHEN year = 2022 THEN sales ELSE 0 END) AS sales_2022,
SUM(CASE WHEN year = 2023 THEN sales ELSE 0 END) AS sales_2023
FROM sales_data
GROUP BY product_category;
6. 多条件排序
场景:实现自定义排序逻辑。
SELECT
product_name,
price,
stock
FROM products
ORDER BY
CASE
WHEN stock <= 10 THEN 0 -- 库存少的优先
WHEN price >= 1000 THEN 1 -- 高价商品次之
ELSE 2
END;
7. 数据验证与约束
场景:在查询中标记异常数据。
SELECT
order_id,
amount,
CASE
WHEN amount < 0 THEN '金额异常'
WHEN amount > 100000 THEN '金额过高'
ELSE '正常'
END AS amount_status
FROM orders;
8. 条件更新(UPDATE语句)
场景:基于条件修改数据。
UPDATE employees
SET salary = CASE
WHEN performance_rating = 'A' THEN salary * 1.2
WHEN performance_rating = 'B' THEN salary * 1.1
ELSE salary
END;
三、性能优化建议
WHEN子句顺序:条件按概率从高到低排列,可提高效率。
避免嵌套过深:多层嵌套CASE影响可读性,可考虑拆分查询或使用临时表。
与聚合函数结合:在聚合函数内使用CASE比先过滤再聚合更高效。
索引使用:CASE中的列如果是索引字段,仍可能利用索引。
四、注意事项
数据类型一致性:所有THEN返回值类型需兼容,否则可能隐式转换。
ELSE可选但建议包含:省略ELSE时,未匹配条件返回NULL。
注意短路逻辑:SQL按WHEN顺序判断,首个满足条件即返回。
兼容性:CASE WHEN是SQL标准语法,主流数据库(MySQL、PostgreSQL、SQL Server等)均支持。
五、进阶示例
-- 复杂条件:结合日期函数和计算字段
SELECT
user_id,
CASE
WHEN last_login_date < DATE_SUB(NOW(), INTERVAL 30 DAY) THEN '流失用户'
WHEN total_orders = 0 THEN '新用户'
WHEN total_orders > 10 AND avg_order_value > 1000 THEN '高价值用户'
ELSE '普通用户'
END AS user_segment
FROM user_stats;
掌握CASE WHEN的灵活应用,可以显著增强SQL查询的数据处理能力,减少应用层代码逻辑负担。