CASE语句中WHEN子句的执行顺序是什么?

37

给定以下 case 语句的主体:

1    WHEN r.code= '00'                        then 'A1'
2    WHEN r.code ='01' AND r.source = 'PXWeb' then 'A2'   <
3    WHEN r.code ='0120'                      then 'A3'
4    WHEN r.code ='01'                        then 'A4'   <
5    WHEN r.code ='1560'                      then 'A5'
6    WHEN r.code ='1530'                      then 'A6'
7    WHEN r.code ='1550'                      then 'A7'

我假设第2行代码总是在第4行之前执行?然后我读到像“SQL是一种声明性语言,这意味着它告诉SQL引擎要做什么,而不是如何做”这样的语句。

SQL查询的执行顺序

我想知道这是否也涉及CASE语句中的执行顺序。基本上,我能否将上面的代码保留不变,而无需更改第4行为

4    WHEN r.code ='01' AND r.source != 'PXWeb' then 'A4'   
3个回答

38
返回结果:

返回的值将是最早(按文本顺序)匹配的WHEN子句的THEN表达式的值。这意味着如果满足第2行的条件,则结果将为A2

但是,如果您的THEN表达式比仅仅是文本值更复杂,则在不需要该表达式时,对其进行评估的一些工作可能会发生。

例如:

 WHEN r.code= '00'                        then 'A1'
 WHEN r.code ='01' AND r.source = 'PXWeb' then 'A2'
 WHEN r.code ='0120'                      then 1/0
 WHEN r.code ='01'                        then 'A4'

即使`r.code`不等于`0120`,甚至等于`00`,也可能会生成除以零的错误。我不知道标准对这个特定问题有什么说法,但我知道某些产品是这样的。

1
我在2008年的草案标准中进行了快速查找,但奇怪的是它似乎没有提到关于case顺序的任何内容。然而,在计算机语言中,通常情况下,case表达式中的case按照指定的顺序进行测试。 - Erwin Smout
1
@ErwinSmout - 我简直不敢相信我从来没有回复过你的评论。这里的区别在于SQL是一种声明性语言,而不是过程性语言。它是根据整体逻辑来指定的,只要它仍然在逻辑上计算出所要求的结果,评估顺序就不应该有影响。不幸的是,一些系统(SQL Server在这里很明显)会产生应该被逻辑排除的错误,从而影响最终结果。理想与现实之间的冲突。 - Damien_The_Unbeliever
“Declarative”是针对数据的物理访问(在RM之前普遍存在的“指针追踪”)而言的。显然,你无法逃避这样一个事实,case表达式实际上只是一种隐含的编写嵌套IF / THEN / ELSE的方式,在某种程度上具有“更多的程序性”。我同意如果“评估顺序不重要”,那将会更好,但不幸的是,证明这一点通常对于任何编译器都是不可行的。这是不可避免的,因此语言定义者必须承担后果。 - Erwin Smout
1
@ErwinSmout - 嗯,它也被设计为帮助暴露并行性。这就是为什么在 SQL 中的许多地方,评估顺序被认为是“好像所有表达式都在并行计算”的原因。也就是说,这就是为什么SELECT子句表达式不能依赖于同一子句中的其他表达式的原因。 - Damien_The_Unbeliever

11

2
但请注意下面的警告,这也是我的回答所警告的:“在某些情况下,表达式在CASE语句接收到其输入结果之前被评估”。 - Damien_The_Unbeliever

2
据我所知,在查询中,CASE的顺序将是您指定的顺序。因此,在您的情况下,评估的顺序将会是1,2,3,4 ... , 7

我是否可以将上面的代码保持不变,而无需更改第4行?

您可以更改第二个CASE并包含一个ELSE部分,如下所示,它将处理第四个CASE的评估,并且您可以完全删除第四个评估。
2    WHEN r.code ='01' AND r.source = 'PXWeb' then 'A2' ELSE 'A4'  

此解决方案将在 r.code = '02' 时输出 'A4',这不是根据问题的预期输出。 - Erdnase

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接