hql运用CASE系列表达式
6.2.2 使用CASE系列表达式
CASE表达式是一个表达式,不是控制语句。也就是说,它返回某个数据类型的值。因为SQL是说明性的,所以不像其他语言中的CASE语句那样可以修改控制流。但是新手们不理解表达式和语句之间的差别,这种程序员的数量多得惊人。
这个思想和语法来自ADA编程语言。这里是< case specification >正式的BNF语法:
<case specification> ::= <simple case> | <searched case> <simple case> ::= CASE <case operand> <simple when clause>... [<else clause>] END <searched case> ::= CASE <searched when clause>... [<else clause>] END <simple when clause> ::= WHEN <when operand> THEN <result> <searched when clause> ::= WHEN <search condition> THEN <result> <else clause> ::= ELSE <result> <case operand> ::= <value expression> <when operand> ::= <value expression> <result> ::= <result expression> | NULL <result expression> ::= <value expression> |
1.搜索格式的CASE表达式
搜索格式的CASE表达式可能是使用最多的表达式版本。WHEN...THEN...子句按照从左向右的顺序执行。第一个测试结果为TRUE的 WHEN子句将返回在它的THEN子句中给出的值可以在CASE表达式中再嵌套CASE表达式。如果对于CASE表达式没有显式地给出ELSE子句,则数据库将插入一个隐式的ELSE NULL子句。如果要在THEN子句中返回NULL,必须使用CAST(NULL AS <数据类型>)表达式。我建议总是给出ELSE子句,这样当你以后发现需要显式地返回某些值时,可以更改它。
2.简单的CASE表达式
<简单的CASE表达式>定义为:在搜索格式的CASE表达式中,所有的WHEN子句都对<case 操作数>做相等性比较。例如
CASE iso_sex_code WHEN 0 THEN 'Unknown' WHEN 1 THEN 'Male' WHEN 2 THEN 'Female' WHEN 9 THEN 'N/A' ELSE NULL END |
也可以写成:
CASE WHEN iso_sex_code = 0 THEN 'Unknown' WHEN iso_sex_code = 1 THEN 'Male' WHEN iso_sex_code = 2 THEN 'Female' WHEN iso_sex_code = 9 THEN 'N/A' ELSE NULL END |
但是这个定义中有一个技巧。表达式
CASE foo WHEN 1 THEN 'bar' WHEN NULL THEN 'no bar' END |
变成:
CASE WHEN foo = 1 THEN 'bar' WHEN foo = NULL THEN 'no_bar' --错误! ELSE NULL END |
第二个WHEN子句总是UNKNOWN。如果简单的CASE表达式适合使用,那么就使用它。
3.其他CASE表达式
SQL-92标准中以CASE表达式的方式定义了其他函数,这样语言会更紧凑一些,并易于实现。例如,COALESCE()函数可以通过下列方式为一个或两个表达式定义:
(1) COALESCE (<value exp #1>)与(<value exp #1>)相同;
(2) COALESCE
(<value exp #1>, <value exp #2>)等同于
CASE WHEN <value exp #1> IS NOT NULL THEN <value exp #1> ELSE <value exp #2> END |
这样我们可以在列表中为n个表达式递归地定义它,这里n>=3:
CASE WHEN <value exp #1> IS NOT NULL THEN <value exp #1> ELSE COALESCE (<value exp #2>, ..., n) END |
同样,NULLIF (<value exp #1>, <value exp #2>)等同于
CASE WHEN <value exp #1> = <value exp #2> THEN NULL ELSE <value exp #1> END |
使用这些CASE表达式中最紧凑的格式,不要将它们扩展到它们的定义之外。