Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server Case语句中的sqlserver函数_Sql Server - Fatal编程技术网

Sql server Case语句中的sqlserver函数

Sql server Case语句中的sqlserver函数,sql-server,Sql Server,SQL Server是否足够聪明,可以在case语句中对datediff函数调用求值一次,然后对每个when子句使用该值?或者函数被调用了“n”次,其中“n”是when子句的数量?很难看出SQL Server如何计算一次调用。该调用有一列作为参数,因此必须对每一行进行求值 因此,您的条件最好写为: select top 10 *, case when datediff(day,DateOfSale, getDate()) > 5 then '5'

SQL Server是否足够聪明,可以在case语句中对
datediff
函数调用求值一次,然后对每个
when
子句使用该值?或者函数被调用了“n”次,其中“n”是
when
子句的数量?

很难看出SQL Server如何计算一次调用。该调用有一列作为参数,因此必须对每一行进行求值

因此,您的条件最好写为:

    select top 10 *, case     
    when datediff(day,DateOfSale, getDate())  > 5 then '5'
        when datediff(day,DateOfSale, getDate())  > 10 then '10'
... (more datediff clauses)
...
...
        else '20'
        end as jack
        from Foo
虽然此查询不会:

select * from YourTable where dt < dateadd(day, -5, getdate())

很难看出SQL Server如何对调用进行一次评估。该调用有一列作为参数,因此必须对每一行进行求值

因此,您的条件最好写为:

    select top 10 *, case     
    when datediff(day,DateOfSale, getDate())  > 5 then '5'
        when datediff(day,DateOfSale, getDate())  > 10 then '10'
... (more datediff clauses)
...
...
        else '20'
        end as jack
        from Foo
虽然此查询不会:

select * from YourTable where dt < dateadd(day, -5, getdate())

当然,但不是在您的情况下(表达式基于表列值,每行都会更改),但在任何情况下,都不要对表列值执行datediff,对谓词(比较)值运行dateadd,这样您的查询仍然可以使用DateOfSale上的任何现有索引

select * from YourTable where datediff(day, DateOfSale, getDate()) > 5
选择前10名*,
当DateOfSale
当然可以,但不是在您的情况下(表达式基于表列值,每行都会更改),但在任何情况下,都不要对表列值执行datediff,对谓词(比较)值运行dateadd,以便您的查询仍然可以使用DateOfSale上的任何现有索引

select * from YourTable where datediff(day, DateOfSale, getDate()) > 5
选择前10名*,
当DateOfSale
令人费解的是,这么多的答案都提到了索引。实际上,<代码> DATEDIF.<代码>不是sgabess,但在这里,当SQLServer中的查询优化器不考虑索引使用(除了试图找到覆盖的可扫描路径)时,这完全是不相关的。据我所知,涉及DATEDIFF的表达式作为索引路径的候选表达式与这个问题完全无关

很容易证明,一旦找到第一个真正的谓词,SQL Server确实会停止对
CASE
语句中的谓词求值

为了证明这一事实,让我们编写一些示例数据:

  select top 10 *, 
      case When DateOfSale < dateadd(day, -20, getDate()) then '20'
           When DateOfSale < dateadd(day, -15, getDate()) then '15'
           When DateOfSale < dateadd(day, -10, getDate()) then '10' 
           When DateOfSale < dateadd(day, -5, getDate()) then '5' 
          else '20' end jack
  from Foo
请注意,如果我们曾经计算过
1/0>1
,那么我们可能会遇到类似
的“被零除的错误”。
。但是,对我的服务器运行此查询会产生十行,在
Jack
列中都有“5”

如果我们去掉前10行,肯定会得到一些行,然后得到被零除的
错误。因此,我们可以安全地得出结论,SQL Server正在对CASE语句进行早期退出评估

除此之外,它还告诉我们:

CASE语句按顺序计算其条件,并以满足条件的第一个条件停止

这个问题可能是想问,公共的
DATEDIFF()
子表达式是否从所有
CASE
语句中提升,计算一次,然后在每个谓词的上下文中进行计算。通过观察
上的
SET SHOWPLAN_TEXT的输出,我认为我们可以得出结论,情况并非如此:

SELECT TOP 10 *, CASE 
WHEN datediff(day,DateOfSale, getDate())  > 5 then '5'
WHEN datediff(day,DateOfSale, getDate())  > 10 then '10'
WHEN 1/0  > 1then 'boom'
ELSE '20' END
AS Jack
FROM Diffy;

由此,我们可以得出结论,这个查询的结构意味着对每一行和每一个谓词计算
DATEDIFF()
,因此
O(rows*predicates)
调用,最坏的情况是。这会给查询带来一些CPU负载,但是
DATEDIFF()
并没有那么昂贵,不应该引起太大的关注。如果在实践中,它最终导致了性能问题,那么有一些方法可以从查询中手动提升计算。例如,
DATEDIFF()。实际上,<代码> DATEDIF.<代码>不是sgabess,但在这里,当SQLServer中的查询优化器不考虑索引使用(除了试图找到覆盖的可扫描路径)时,这完全是不相关的。据我所知,涉及DATEDIFF的表达式作为索引路径的候选表达式与这个问题完全无关

很容易证明,一旦找到第一个真正的谓词,SQL Server确实会停止对
CASE
语句中的谓词求值

为了证明这一事实,让我们编写一些示例数据:

  select top 10 *, 
      case When DateOfSale < dateadd(day, -20, getDate()) then '20'
           When DateOfSale < dateadd(day, -15, getDate()) then '15'
           When DateOfSale < dateadd(day, -10, getDate()) then '10' 
           When DateOfSale < dateadd(day, -5, getDate()) then '5' 
          else '20' end jack
  from Foo
请注意,如果我们曾经计算过
1/0>1
,那么我们可能会遇到类似
的“被零除的错误”。
。但是,对我的服务器运行此查询会产生十行,在
Jack
列中都有“5”

如果我们去掉前10行,肯定会得到一些行,然后得到被零除的
错误。因此,我们可以安全地得出结论,SQL Server正在对CASE语句进行早期退出评估

除此之外,它还告诉我们:

CASE语句按顺序计算其条件,并以满足条件的第一个条件停止

这个问题可能是想问,公共的
DATEDIFF()
子表达式是否从所有
CASE
语句中提升,计算一次,然后在每个谓词的上下文中进行计算。通过观察
上的
SET SHOWPLAN_TEXT的输出,我认为我们可以得出结论,情况并非如此:

SELECT TOP 10 *, CASE 
WHEN datediff(day,DateOfSale, getDate())  > 5 then '5'
WHEN datediff(day,DateOfSale, getDate())  > 10 then '10'
WHEN 1/0  > 1then 'boom'
ELSE '20' END
AS Jack
FROM Diffy;
由此,我们可以得出结论,该查询的结构意味着对每一行和每一行计算
DATEDIFF()