Nic*_*ndo 7 sql t-sql sql-server
我正试图在列表中使用a 中的put CASE
语句,并找到一些我不理解的奇怪行为.这是一些代码:ORDER BY
DISTINCT
SELECT
select distinct Requester, ISO_ID as ISO, (ISO_ID - 5 + 50) AS 'someNum', BU
from LoanerHeader order by
CASE WHEN 'a' = 'b' then Requester
when 'b' = 'c' then BU
else ISO_ID
end
Run Code Online (Sandbox Code Playgroud)
这有效.但是,如果我将第4行更改为when 'b' = 'b' then BU
:
select distinct Requester, ISO_ID as ISO, (ISO_ID - 5 + 50) AS 'someNum', BU
from LoanerHeader order by
CASE WHEN 'a' = 'b' then Requester
when 'b' = 'b' then BU
else ISO_ID
end
Run Code Online (Sandbox Code Playgroud)
它打破了错误:
如果指定了SELECT DISTINCT,则ORDER BY项必须出现在选择列表中.
什么时候BU
显然在选择列表中.更奇怪的是当我将代码更改为:
select distinct Requester, ISO_ID as ISO, (ISO_ID - 5 + 50) AS 'someNum', BU
from LoanerHeader order by
CASE WHEN 'a' = 'b' then Requester
when 'b' = 'b' then BU
else BU --change is here
end
Run Code Online (Sandbox Code Playgroud)
它又有效了!这怎么有意义呢?有人能帮我把这个脑袋包裹起来吗?
规则CASE
是结果应该转换为具有最高优先级的分支的数据类型.
对于第一个查询,它使用矛盾检测,只生成一个ISO_ID
直接排序的计划.这已经是数字,所以不需要隐式转换,因此匹配选择列表中的表达式没有问题.
对于第二个查询,它可以在编译时再次确定它需要ORDER BY BU
.除了它实际上需要ORDER BY CAST(BU AS NUMERIC)
由于上述.这意味着它需要ORDER BY
一个计算表达式,不匹配SELECT
列表中的任何内容.因此问题.
您的第三个查询从中删除了更高优先级的表达式,CASE
从而消除了对隐式强制转换的需要(因此需要按计算表达式排序).
由于计算表达式完全取决于SELECT DISTINCT
列表中的列,但您可以按如下方式重写第二个查询.
;WITH CTE AS
(
SELECT DISTINCT Requester,
ISO_ID AS ISO,
( ISO_ID - 5 + 50 ) AS 'someNum',
BU
FROM LoanerHeader
)
SELECT *
FROM CTE
ORDER BY CASE
WHEN 'a' = 'b' THEN Requester
WHEN 'b' = 'b' THEN BU
ELSE ISO
END
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4381 次 |
最近记录: |