hql运用CASE系列表达式

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表达式中最紧凑的格式,不要将它们扩展到它们的定义之外。