|
我正在尝试使用列表中的a来将CASE语句放入ORDER BY子句中,并发现一些我不理解的奇怪行为。这是一些代码:DISTINCT``SELECT
& x$ E3 Q( ^0 f8 z# _% D8 \* Hselect distinct Requester, ISO_ID as ISO, (ISO_ID - 5 + 50) AS 'someNum', BU* W7 t( V9 R) ^# _1 U
from LoanerHeader order by0 L( C |: l# ?, R; s
CASE WHEN 'a' = 'b' then Requester, \. t) H ?1 d) q4 B9 W4 F4 c$ [
when 'b' = 'c' then BU% `7 e$ Y `4 q Z2 s' i8 }: z
else ISO_ID
0 k$ E. F5 r* F4 kend
9 k+ H1 i1 F& M8 ^这行得通。但是,如果我将第四行更改为when 'b' = 'b' then BU:: n/ S# _% Q( U5 h& m
select distinct Requester, ISO_ID as ISO, (ISO_ID - 5 + 50) AS 'someNum', BU( s6 @6 d: B) m* x' S( X6 A5 T; L
from LoanerHeader order by) J& @7 v. i: c1 D
CASE WHEN 'a' = 'b' then Requester8 o& U& L4 j) {2 c$ g& p/ X+ N7 r
when 'b' = 'b' then BU6 X; y3 B; {1 D) n4 Y+ v1 |
else ISO_ID
# R( `) W% o1 r/ o' Pend! z6 B# p, j) e+ v
它因错误而中断:
, O: [# s) u6 U9 J8 M2 w# f1 m9 [5 n
如果指定了SELECT DISTINCT,则ORDER BY项目必须出现在选择列表中。9 o% O4 H% T- S2 U* g1 }+ T
^& s" J" t; u0 v1 I
当BU显然是在选择列表中。甚至更陌生的是当我将代码更改为:
* R& C5 R- ]8 W0 F/ \select distinct Requester, ISO_ID as ISO, (ISO_ID - 5 + 50) AS 'someNum', BU, b; i. D, _0 H; W( s1 ?
from LoanerHeader order by
5 ?9 m& Y# T& K1 I$ MCASE WHEN 'a' = 'b' then Requester9 ^& {7 ?( V T, @9 E7 k
when 'b' = 'b' then BU
6 d. C; ^4 F' D) m \7 Z' selse BU --change is here
8 [" j3 ]5 Q- B# P1 D( b' Cend
9 _8 }3 i x. I/ d0 y( @; Z它再次起作用!这甚至有道理吗?有人可以帮我绕过这个大脑吗?' d/ {; \2 K" Z& o# R
( `; N6 P" }# d* {1 P2 U解决方案:
& \6 ^8 D/ i8 J ! p7 N% l9 Q+ | E* J0 _
0 R, a+ p& h) [
: K9 Z& C e8 c* M6 { 规则CASE是将结果强制转换为具有最高优先级的分支的数据类型。/ W& w5 H! R! T3 u8 h
对于第一个查询,它使用矛盾检测,并且仅生成ISO_ID直接排序的计划。这已经是数字了,因此不需要隐式转换,因此可以毫无问题地匹配选择列表中的表达式。" Y! G! F; k3 I& d7 M: ~! i
对于第二个查询,它可以再次在编译时确定它需要进行的操作ORDER BY BU。ORDER BY CAST(BU AS
3 l9 p, h! d9 R9 a, H1 B# VNUMERIC)由于上述原因,除实际需要外。这意味着它将需要ORDER BY一个不与SELECT列表中任何内容匹配的计算表达式。因此出现了问题。
u* \; v. X' A0 S7 u, q: ~, L# n您的第三个查询从中删除了优先级更高的表达式,CASE从而消除了对隐式强制转换的需要(并因此消除了对计算表达式进行排序的需要)。* `; z, s4 ]6 d4 g
由于计算的表达式完全取决于SELECT DISTINCT列表中的列,但是您可以按如下方式重写第二个查询。8 C( h# j+ Q9 h
;WITH CTE AS
- { \+ w/ G: `% O' Y2 S(
: Y( k- o+ g0 b9 \; @( OSELECT DISTINCT Requester,
7 I. X3 k8 I( d ISO_ID AS ISO,+ V! y9 o- x6 i3 W! A9 J& \
( ISO_ID - 5 + 50 ) AS 'someNum',& X) v1 o& g8 w8 D$ c! l( l
BU; J" K; c, a: }2 u; e5 t
FROM LoanerHeader
3 C8 _3 {: z; [4 [/ d, e9 f; Q)
: c' a2 d3 a9 t* R7 B" G# zSELECT *7 D, m0 X* W1 t
FROM CTE
" f+ q( Y8 q" C% c& `ORDER BY CASE0 G& k. l, s5 W4 B/ B; x
WHEN 'a' = 'b' THEN Requester
( `; k' Z. q& D% N" _$ W0 o# H WHEN 'b' = 'b' THEN BU
3 y, E0 k( _. k* i ELSE ISO& O# G, V0 w+ Z$ b9 |: z% C. ?8 W
END |
|