gpt4 book ai didi

sql - SQL Server 在窗口函数子句中奇怪的不一致行为?

转载 作者:行者123 更新时间:2023-12-02 16:38:24 25 4
gpt4 key购买 nike

询问时another question ,我发现 SQL Server(发生在 2005 年和 2008 年)在处理窗口函数子句中的 CASE 语句时似乎有奇怪的不一致行为。下面的代码会报错:

declare @t table (SortColumn int)
insert @t values (1), (2), (3)
declare @asc bit
set @asc = 0

select row_number() over (order by
case when 1=1 then SortColumn end asc,
case when 1=0 then SortColumn end desc) RowNumber
, *
from @t

错误是窗口函数不支持常量作为 ORDER BY 子句表达式。我认为这是因为 case 语句的计算结果可能为 NULL,这是一个常数。正如所料,此代码给出了相同的错误:

declare @t table (SortColumn int)
insert @t values (1), (2), (3)
declare @asc bit
set @asc = 0

select row_number() over (order by
NULL asc,
NULL desc) RowNumber
, *
from @t

...大概是出于同样的原因。但是,此代码不会给出错误:

declare @t table (SortColumn int)
insert @t values (1), (2), (3)
declare @asc bit
set @asc = 0

select row_number() over (order by
case when @asc=1 then SortColumn end asc,
case when @asc=0 then SortColumn end desc) RowNumber
, *
from @t

与第一个代码块的唯一区别是我已将 case 语句的条件操作数之一移至变量 @asc 中。现在效果很好。但为什么呢? case 语句的计算结果可能仍为 NULL,它是一个常量,因此它不应该起作用……但它确实起作用。这是一致的,还是微软提出的特殊情况行为?

所有这些行为都可以通过使用 this query 来检查.

<小时/>

更新:此限制不仅适用于 OVER 子句(尽管它们确实给出了不同的错误) - 它适用于所有 ORDER BY 子句自 SQL Server 2005 起。 Here's a query它还显示了常规 SELECTORDER BY 子句的限制。

最佳答案

在线书籍指出“排序列可以包含表达式,但当数据库处于 SQL Server (90) 兼容模式时,该表达式无法解析为常量。”但是它没有定义“常数”。

通过思考和一些实验,似乎很清楚这意味着可以在编译时成功计算文字常量值的表达式。

/*Works - Constant at run time but SQL Server doesn't do variable sniffing*/
DECLARE @Foo int
SELECT ROW_NUMBER() OVER (ORDER BY @Foo)
FROM master..spt_values

/*Works - Constant folding not done for divide by zero*/
SELECT ROW_NUMBER() OVER (ORDER BY $/0)
FROM master..spt_values

/*Fails - Windowed functions do not support
constants as ORDER BY clause expressions.*/
SELECT ROW_NUMBER() OVER (ORDER BY $/1)
FROM master..spt_values

关于sql - SQL Server 在窗口函数子句中奇怪的不一致行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7204979/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com