`CASE WHEN` 在 ClickHouse 与 Mysql 中的重点使用场景总结笔记
时间:2025-7-14 10:23 作者:wanzi 分类: 数据库
📘 CASE WHEN
使用场景总结(MySQL & ClickHouse)
CASE WHEN
是 SQL 中用于实现条件逻辑的控制流函数,类似于编程语言中的 if-else
。它在数据查询、清洗、转换、排序等操作中非常有用,是 SQL 开发中不可或缺的一部分。
虽然 CASE WHEN
的基本语法在不同数据库中相似,但其性能和适用场景略有差异。以下是对 MySQL 和 ClickHouse 中 CASE WHEN
的重点使用场景总结。
✅ 一、基本语法结构
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
...
ELSE result_default
END
✅ 二、MySQL 中 CASE WHEN
常见使用场景
1. 字段值映射 / 转换
将某个字段的值映射为另一个可读性更强的值:
SELECT name,
CASE gender
WHEN 'M' THEN '男'
WHEN 'F' THEN '女'
ELSE '未知'
END AS gender_label
FROM users;
2. 动态列计算
根据不同的条件生成新的计算字段:
SELECT order_id, amount,
CASE
WHEN amount > 1000 THEN amount * 0.9
WHEN amount BETWEEN 500 AND 1000 THEN amount * 0.95
ELSE amount
END AS discounted_amount
FROM orders;
3. 条件过滤(替代 OR 或 IN)
某些复杂的多条件筛选可以用 CASE WHEN
实现更清晰的逻辑:
SELECT *
FROM employees
WHERE CASE
WHEN department = 'IT' AND salary > 8000 THEN 1
WHEN department = 'HR' AND salary > 6000 THEN 1
ELSE 0
END = 1;
⚠️ 注意:这种方式在 MySQL 中可能不如
WHERE ... OR ...
高效,适用于逻辑复杂时。
4. 自定义排序
对非自然顺序的字段进行排序(如状态、优先级等):
SELECT status, COUNT(*) as count
FROM tasks
GROUP BY status
ORDER BY
CASE status
WHEN '未开始' THEN 1
WHEN '进行中' THEN 2
WHEN '已完成' THEN 3
ELSE 4
END;
5. 行转列(Pivot)
常用于报表统计,将多行数据合并为一行展示:
SELECT user_id,
SUM(CASE WHEN subject = '数学' THEN score ELSE 0 END) AS math_score,
SUM(CASE WHEN subject = '语文' THEN score ELSE 0 END) AS chinese_score
FROM scores
GROUP BY user_id;
✅ 三、ClickHouse 中 CASE WHEN
常见使用场景
ClickHouse 对 CASE WHEN
支持良好,但由于其列式存储和向量化执行引擎,在大数据量下表现优异。
1. 字段映射与分类
与 MySQL 类似,常用于字段值的映射或标签化:
SELECT event_type,
CASE
WHEN event_type = 1 THEN '点击'
WHEN event_type = 2 THEN '浏览'
WHEN event_type = 3 THEN '下单'
ELSE '其他'
END AS event_name
FROM events;
2. 自定义排序(推荐使用 transform 替代)
虽然 CASE WHEN
可以实现自定义排序,但在 ClickHouse 中推荐使用更高效的 transform()
函数:
SELECT level
FROM vuln
ORDER BY
CASE level
WHEN 'super' THEN 1
WHEN 'high' THEN 2
WHEN 'middle' THEN 3
WHEN 'low' THEN 4
END;
✅ 推荐写法(更高效):
SELECT level
FROM vuln
ORDER BY transform(
level,
['super', 'high', 'middle', 'low'],
CAST([1, 2, 3, 4], 'Array(UInt8)'),
5::UInt8
)
3. 条件聚合
结合 GROUP BY
和 SUM/COUNT
等聚合函数,做条件统计:
SELECT country,
COUNT() AS total_users,
SUM(CASE WHEN is_active THEN 1 ELSE 0 END) AS active_users
FROM users
GROUP BY country;
4. 数据清洗 / 替换 NULL 值
用于处理缺失值或非法值:
SELECT user_id,
CASE
WHEN age < 0 THEN NULL
ELSE age
END AS cleaned_age
FROM users;
5. 事件分组分析
根据时间或其他维度进行分组判断,用于漏斗分析、用户行为等:
SELECT user_id,
MAX(CASE WHEN event = '注册' THEN event_time END) AS reg_time,
MAX(CASE WHEN event = '下单' THEN event_time END) AS order_time
FROM user_events
GROUP BY user_id;
✅ 四、MySQL vs ClickHouse 的区别总结
场景 | MySQL | ClickHouse |
---|---|---|
性能 | 小数据集友好 | 大数据集高性能 |
行转列 | 经常用 CASE WHEN + GROUP BY |
同样支持,但也可以用物化视图优化 |
自定义排序 | 支持 CASE WHEN |
推荐用 transform() 更高效 |
条件计算 | 支持 | 支持,向量化执行更快 |
数据清洗 | 支持 | 支持,适合批量处理 |
✅ 五、小贴士
- 在 ClickHouse 中尽量避免在
WHERE
中使用CASE WHEN
,会影响索引效率。 CASE WHEN
是 SQL 标准函数,具有良好的兼容性。- 如果只是简单的值映射,考虑使用字典表或枚举类型代替
CASE WHEN
。 - 在 ClickHouse 中,对于静态映射建议使用
transform()
,性能更好。
✅ 六、结语
无论是 MySQL 还是 ClickHouse,CASE WHEN
都是非常实用的工具,尤其在数据清洗、分类、条件判断、报表统计等方面应用广泛。理解它的使用场景和性能特点,可以帮助你写出更清晰、高效的 SQL 查询。
如果你需要我把这份笔记导出为 Markdown 或 PDF 文档,也可以告诉我 😊