sql-server - SELECT CASE 与 SQL 中的 CASE

标签 sql-server sql-server-2008 tsql

我不太明白为什么这两个不同的代码示例返回不同的值。

不知何故不正确但有效的语法,返回错误的结果,例如它返回 0当比较结束时 两个相等 值(value)观:

(SELECT CASE 
    WHEN 
       SUM(V.IsCompatible) OVER 
          (PARTITION BY ComputerName, UserID) = ApplicationCount 
    THEN 1 ELSE 0 END
) AS CompatibleUser

下面的一个返回 正确的值 , IE。 1当有 两个相等的值 比较的。
(CASE 
    WHEN 
       SUM(V.IsCompatible) OVER 
         (PARTITION BY ComputerName, UserID) = ApplicationCount 
    THEN 1 ELSE 0 END
) AS CompatibleUser

甚至更简单:
(SELECT CASE 
    WHEN 
       X = Y 
    THEN 1 ELSE 0 END
) AS Result

X = 22 AND Y = 22 => 结果 = 0
(CASE 
    WHEN 
       X = Y 
    THEN 1 ELSE 0 END
) AS Result

X = 22 AND Y = 22 => 结果 = 1

我明白 应用正确的语法 很重要,我知道 T-SQL 中的 SELECT CASE 语法,但我不明白 评估第一个代码示例 并带来意想不到的结果。

更新:在其上下文中的完整查询
select userapplication.username,
   computerdetails.computername,
   sum(userapplication.iscompatible) 
       over (partition by computerdetails.computername, 
                          userapplication.userid) as compatiblecount,
   userapplication.applicationcount,
   ( case
       when sum(userapplication.iscompatible) 
           over (partition by 
           computerdetails.computername, 
           userapplication.userid) <> userapplication.applicationcount 
       then 0
       else 1
     end 
   ) as usercomputeriscompatible
from   computerdetails
   right outer join usercomputer
     on computerdetails.computerid = usercomputer.computerid
   right outer join userapplication
     on usercomputer.gebruikerid = userapplication.userid 

所以userComputerIsCompatible是这里有问题的结果

最佳答案

我认为这种行为的原因是下一个:像 (SELECT ...) 这样的表达式即使没有 FROM 也被认为是子查询条款。假设这些(假)“子查询”的数据源只是当前行。所以,(SELECT expression)被解释为 (SELECT expression FROM current_row)(SELECT SUM(iscompatible)OVER(...))执行为 (SELECT SUM(iscompatible)OVER(current_row)) .

参数:分析 (SELECT SUM(IsWeb) OVER(PARTITION BY OrderDate) [FROM current_row]) 的执行计划表达
enter image description here

我看到一个 Constant Scan (Scan an internal table of constants)运算符而不是 Clustered Index Scan之前 SegmentStream Aggregate ( [Expr1007] = Scalar Operator(SUM(@OrderHeader.[IsWeb] as [h].[IsWeb])) ) 运算符。此内部表 ( Constant Scan ) 是从当前行构造的。

示例(使用 SQL2005SP3 和 SQL2008 测试):

DECLARE @OrderHeader TABLE
(
     OrderHeaderID  INT IDENTITY PRIMARY KEY
    ,OrderDate      DATETIME NOT NULL
    ,IsWeb          TINYINT NOT NULL --or BIT
);
INSERT  @OrderHeader 
SELECT  '20110101', 0
UNION ALL 
SELECT  '20110101', 1
UNION ALL
SELECT  '20110101', 1
UNION ALL 
SELECT  '20110102', 1
UNION ALL
SELECT  '20110103', 0
UNION ALL
SELECT  '20110103', 0;

SELECT  *
        ,SUM(IsWeb) OVER(PARTITION BY OrderDate) SumExpression_1
FROM    @OrderHeader h
ORDER BY h.OrderDate;

SELECT  *
        ,(SELECT SUM(IsWeb) OVER(PARTITION BY OrderDate)) SumWithSubquery_2
FROM    @OrderHeader h
ORDER BY h.OrderDate;

结果:
OrderHeaderID OrderDate               IsWeb SumExpression_1
------------- ----------------------- ----- ---------------
1             2011-01-01 00:00:00.000 0     2
2             2011-01-01 00:00:00.000 1     2
3             2011-01-01 00:00:00.000 1     2
4             2011-01-02 00:00:00.000 1     1
5             2011-01-03 00:00:00.000 0     0
6             2011-01-03 00:00:00.000 0     0

OrderHeaderID OrderDate               IsWeb SumWithSubquery_2
------------- ----------------------- ----- -----------------
1             2011-01-01 00:00:00.000 0     0
2             2011-01-01 00:00:00.000 1     1
3             2011-01-01 00:00:00.000 1     1
4             2011-01-02 00:00:00.000 1     1
5             2011-01-03 00:00:00.000 0     0
6             2011-01-03 00:00:00.000 0     0

关于sql-server - SELECT CASE 与 SQL 中的 CASE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8006853/

相关文章:

sql-server - 将XML直接从SQL Server输出到文件

c# - 如何从使用 exec() 的存储过程创建复杂类型?

sql-server - CopyFromRecordset 返回奇怪的字符

tsql - 用于生成 slug 的 T-SQL 函数?

sql - 如何在执行计划中找到Expr####

sql-server - 将文件上传到 Azure Blob 存储时触发 SSIS 包

sql - 如何动态决定在 SQL Server 存储过程中加入哪些表

sql - 如何在sql server中找到这个模式?

sql-server - 使用连接从左表中获取所有数据

sql-server - 我收到此错误 : Only one expression can be specified in the select list when the subquery is not introduced with EXISTS