CASE WHEN 是 SQL 中非常重要且强大的条件表达式,它在 Impala 中的用法与其他标准 SQL 数据库非常相似,主要用于实现条件逻辑。
基本语法
CASE WHEN 有两种主要形式:
1. 简单 CASE 表达式
这种形式将一个表达式与一组简单的值进行比较。
CASE column_name
WHEN value1 THEN result1
WHEN value2 THEN result2
...
[ELSE else_result]
END
执行过程:它拿 CASE 后面的表达式(通常是列名)与每个 WHEN 后面的值进行相等比较。如果匹配,则返回对应的 THEN 后面的结果。
2. 搜索 CASE 表达式
这种形式更灵活,可以在每个 WHEN 子句中指定复杂的布尔条件。
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
...
[ELSE else_result]
END
执行过程:它按顺序评估每个 WHEN 后面的条件。第一个为真的条件将返回其对应的 THEN 结果。如果所有条件都不为真,则返回 ELSE 子句的结果;如果未提供 ELSE,则返回 NULL。
详细用法与示例
假设我们有一张 sales 表:
| id | product | category | amount | region |
|---|---|---|---|---|
| 1 | Laptop | Tech | 1500 | North |
| 2 | Chair | Furniture | 200 | South |
| 3 | Phone | Tech | 800 | East |
| 4 | Desk | Furniture | 450 | West |
| 5 | Mouse | Tech | 50 | North |
示例 1:简单 CASE 表达式(基于枚举值)
将区域翻译为中文:
SELECT
region,
CASE region
WHEN 'North' THEN '北方'
WHEN 'South' THEN '南方'
WHEN 'East' THEN '东方'
WHEN 'West' THEN '西方'
ELSE '其他'
END AS region_chinese
FROM sales;
结果:
| region | region_chinese |
|---|---|
| North | 北方 |
| South | 南方 |
| East | 东方 |
| West | 西方 |
| North | 北方 |
示例 2:搜索 CASE 表达式(基于条件)
根据销售额度对订单进行分类:
SELECT
id,
amount,
CASE
WHEN amount > 1000 THEN '大订单'
WHEN amount > 500 THEN '中等订单'
WHEN amount > 100 THEN '小订单'
ELSE '微量订单'
END AS order_size
FROM sales;
结果:
| id | amount | order_size |
|---|---|---|
| 1 | 1500 | 大订单 |
| 2 | 200 | 小订单 |
| 3 | 800 | 中等订单 |
| 4 | 450 | 小订单 |
| 5 | 50 | 微量订单 |
注意:CASE WHEN 是按顺序判断的,一旦某个条件为真,就会返回结果并停止后续判断。所以上面的例子中,amount = 1500 虽然也满足 amount > 500,但它首先满足了 amount > 1000,所以被归类为“大订单”。
示例 3:在聚合函数中使用 CASE WHEN
这是 CASE WHEN 一个非常强大的用法,可以实现有条件的计数和求和。
统计每个区域“高价值订单”(金额 > 500)的数量:
SELECT
region,
COUNT(*) AS total_orders,
-- 核心:只有当 amount > 500 时,才计入 1,否则计入 0
SUM(CASE WHEN amount > 500 THEN 1 ELSE 0 END) AS high_value_orders
FROM sales
GROUP BY region;
结果:
| region | total_orders | high_value_orders |
|---|---|---|
| North | 2 | 1 |
| South | 1 | 0 |
| East | 1 | 1 |
| West | 1 | 0 |
计算每个类别的总销售额,并单独列出 Tech 类别的销售额:
SELECT
category,
SUM(amount) AS total_amount,
-- 核心:只对 Tech 类别的金额求和,非 Tech 类别加 0
SUM(CASE WHEN category = 'Tech' THEN amount ELSE 0 END) AS tech_amount
FROM sales
GROUP BY category;
结果:
| category | total_amount | tech_amount |
|---|---|---|
| Tech | 2350 | 2350 |
| Furniture | 650 | 0 |
示例 4:在 UPDATE 语句中使用(Impala 支持有限)
请注意,Impala 传统上主要用于查询(OLAP),其对 UPDATE 和 DELETE 的支持在 Kudu 表中才更完善。语法如下:
-- 假设表是存储在 Kudu 中的
UPDATE sales
SET amount =
CASE
WHEN region = 'North' THEN amount * 1.1 -- 北方区域涨价10%
ELSE amount
END
WHERE ... ; -- 最好加上 WHERE 条件,否则会更新所有行
示例 5:在 ORDER BY 中使用
实现自定义排序规则,让 Tech 类别排在最前面,然后是 Furniture,最后是其他。
SELECT *
FROM sales
ORDER BY
CASE category
WHEN 'Tech' THEN 1
WHEN 'Furniture' THEN 2
ELSE 3
END;
示例 6:处理 NULL 值
SELECT
name,
CASE
WHEN comments IS NULL THEN '暂无评论'
ELSE comments
END AS processed_comments
FROM some_table;
注意事项与最佳实践
- 类型一致性:
THEN和ELSE子句返回的所有结果值必须是兼容的数据类型(例如,不能在一个分支返回字符串,在另一个分支返回数字)。 ELSE子句是好的习惯:总是包含ELSE子句可以确保在所有条件都不满足时有一个明确的默认值,避免意外的NULL。- 性能:
CASE WHEN是按顺序评估的。将最可能被满足的条件或者开销最小的条件放在前面,可以提高查询效率。 - 结尾:不要忘记以
END关键字结束CASE表达式。 - Impala 版本:确保你使用的 Impala 版本支持你所需要的所有 SQL 功能。大部分基本的
CASE WHEN功能在所有现代版本的 Impala 中都得到了支持。
总结
CASE WHEN 是 Impala SQL 中实现流控制的核心结构,其用法可以总结为:
| 场景 | 推荐形式 | 示例 |
|---|---|---|
| 简单值匹配 | 简单 CASE | CASE status WHEN 'A' THEN 'Active' ... END |
| 复杂条件判断 | 搜索 CASE | CASE WHEN score >= 90 THEN 'A' ... END |
| 条件聚合 | 在聚合函数中使用搜索 CASE | SUM(CASE WHEN ... THEN 1 ELSE 0 END) |
| 数据清洗/转换 | 搜索 CASE | CASE WHEN col IS NULL THEN 'N/A' ELSE col END |
熟练掌握 CASE WHEN 能极大地增强你进行数据转换、清洗和业务逻辑计算的能力。

836

被折叠的 条评论
为什么被折叠?



