区间判断必须用搜索case配合>=、between或and组合,不可用等值匹配;条件须从高到低顺序排列以防“截胡”,null需显式判断,where中应优先使用原生布尔表达式而非case。

CASE WHEN怎么写区间判断条件
直接用 BETWEEN 或逻辑组合(AND)写范围,别用 = 去硬碰数值——区间不是离散点。常见错误是把 CASE WHEN score = 80 THEN 'B' 当成区间,结果只匹配恰好 80 的记录,漏掉 80–89 整个段。
正确写法是显式定义上下界:
SELECT
name,
CASE
WHEN score >= 90 THEN 'A'
WHEN score >= 80 THEN 'B' -- 自动排除了已匹配的 >=90,无需写 score = 70 THEN 'C'
ELSE 'F'
END AS grade
FROM students;
注意:条件顺序很重要,WHEN 是从上到下逐条匹配,一旦命中就跳出,后续不管。所以高区间的要放前面,否则会被低区间“截胡”。
NULL值和边界重叠怎么处理
如果字段可能为 NULL,它不会进入任何 WHEN score >= X 分支(因为 NULL >= 90 结果是 UNKNOWN,不是 TRUE),最终落到 ELSE。但有时你希望单独标出空值,就得显式判断:
- 加一条
WHEN score IS NULL THEN 'MISSING',放在所有数值判断之前或之后都行(推荐放最前,语义清晰) - 避免边界重叠,比如同时写
WHEN score 和 <code>WHEN score >= 80,中间没留缝还可能冲突;用“左闭右开”或“左闭右闭但错位”更稳,例如:>= 80 AND - 整数字段用
>=/更安全;如果是小数或带精度的字段(如 <code>DECIMAL(5,2)),务必确认边界是否包含端点
在GROUP BY里用CASE WHEN分组聚合
不能直接在 GROUP BY 里重复写一长串 CASE WHEN,容易出错且难维护。应该先在 SELECT 中定义别名,再在 GROUP BY 引用该别名(多数数据库如 PostgreSQL、SQL Server 支持;MySQL 8.0+ 也支持,但旧版不认别名,得复制表达式)。
安全写法(兼容性更好):
SELECT
CASE
WHEN amount >= 1000 THEN 'high'
WHEN amount >= 100 THEN 'mid'
ELSE 'low'
END AS level,
COUNT(*) AS cnt,
AVG(amount) AS avg_amt
FROM orders
GROUP BY
CASE
WHEN amount >= 1000 THEN 'high'
WHEN amount >= 100 THEN 'mid'
ELSE 'low'
END;
性能提示:如果表很大,这个表达式会在每行计算一次,且无法利用 amount 字段上的普通 B-tree 索引加速范围判断——优化器通常没法把 CASE 映射到索引扫描。真要高频查询,考虑加生成列或物化分组字段。
WHERE里能用CASE WHEN过滤区间吗
能,但没必要,也容易写错。绝大多数场景直接用原字段条件更高效、更易读:
- ✅ 推荐:
WHERE score >= 80 AND score - ❌ 不推荐:
WHERE CASE WHEN score >= 80 AND score —— 多一层计算,还可能让优化器放弃索引 - ⚠️ 唯一合理用例:当过滤逻辑必须依赖多个字段组合判断,且无法拆成简单布尔表达式时,才考虑在
WHERE里用CASE,例如:WHERE (CASE WHEN type = 'A' THEN value ELSE backup_value END) > 100
区间分组本质是分类逻辑,CASE WHEN 是它的自然载体;但过滤是检索动作,优先交给原生比较运算符。











