添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

SQL专题(十五)case表达式

ELSE 子句也可以省略不写,这时会被默认为ELSE NULL。但为了防止有人漏读,还是希望大家能够显示地写出ELSE 子句。

我们在编写 SQL 语句的时候需要注意,在发现为真的 WHEN 子句 时,CASE 表达式的真假值判断就会中止,而剩余的 WHEN 子句会被 忽略。为了避免引起不必要的混乱,使用 WHEN 子句时要注意条件的 排他性。

新手用 WHERE 子句进行条件分支,高手用 SELECT 子句进行条件分 支。

CASE 表达式用在 SELECT 子句里时, 既可以写在聚合函数内部,也可以写在聚合函数外部。这种高度自由 的写法正是 CASE 表达式的魅力所在。

CASE 表达式经常会因为同 VB 和 C 语言里 的 CASE “语句”混淆而被叫作 CASE 语句。但是准确来说,它并不是 语句,而是和 1+1 或者 a/b 一样属于表达式的范畴。结束符 END 确 实看起来像是在标记一连串处理过程的终结,所以初次接触 CASE 表 达式的人容易对这一点感到困惑。“表达式”和“语句”的名称区别恰恰 反映了两者在功能处理方面的差异。

case表达式可以放置的位置

作为表达式,CASE 表达式在执行时会被判定为一个固定值,因此它 可以写在聚合函数内部;也正因为它是表达式,所以还可以写在

  • SELECE 子句、
  • GROUP BY 子句、
  • WHERE 子句、
  • ORDER BY 子句里。

简 单点说,在能写列名和常量的地方,通常都可以写 CASE 表达式。

从 这个意义上来说,与 CASE 表达式最接近的不是面向过程语言里的 CASE 语句,而是 Lisp 和 Scheme 等函数式语言里的 case 和 cond 这 样的条件表达式


case兼具where和having的功能。

CASE 表达式是支撑 SQL 声明式编程的根基之一


case 表达式的两类写法

1.简单case表达式

2.搜索case表达式

-- 使用搜索CASE表达式的情况(重写代码清单6-41) 
SELECT product_name,      
CASE WHEN product_type = '衣服'   THEN 'A :' | |product_type 
WHEN product_type = '办公用品'   THEN 'B :' | |product_type 
WHEN product_type = '厨房用具'   THEN 'C :' | |product_type           
ELSE NULL       
END AS abc_product_type  
FROM Product;
-- 使用简单CASE表达式的情况 
SELECT product_name,       
CASE product_type           
 WHEN '衣服' THEN 'A :' | | product_type           
 WHEN '办公用品' THEN 'B :' | | product_type            
WHEN '厨房用具' THEN 'C :' | | product_type            
ELSE NULL        
END AS abc_product_type  
FROM Product;

特定的case表达式

oravle中的decode,

mysql中的if

hive中的nvl

presto中的coalesce等


注意事项

注意事项 1:统一各分支返回的数据类型

注意事项 2:不要忘了写 END

注意事项 3:养成写 ELSE 子句的习惯

不写 ELSE 子 句时,CASE 表达式的执行结果是 NULL 。但是不写可能会造成“语法 没有错误,结果却不对”这种不易追查原因的麻烦,所以最好明确地 写上 ELSE 子句(即便是在结果可以为 NULL 的情况下)。养成这样 的习惯后,我们从代码上就可以清楚地看到这种条件下会生成 NULL ,而且将来代码有修改时也能减少失误。

使用方法

将已有编号方式转换为新的方式并统计

条件判断,写计算字段,并group by

在 GROUP BY 子句里使用 CASE 表达式,可以灵活地选择作为聚 合的单位的编号或等级。这一点在进行非定制化统计时能发挥巨 大的威力。

用一条 SQL 语句进行不同条件的统计---经典的行转列用法

在聚合函数中使用 CASE 表达式,可以轻松地将行结构的数据转 换成列结构的数据。

SELECT pref_name,       
-- 男性人口       
SUM( CASE WHEN sex = '1' THEN population ELSE 0 END) AS cnt_m,