我不太明白为什么这两个不同的代码示例返回不同的值。
不知何故不正确但有效的语法,返回错误的结果,例如它返回 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])
的执行计划表达
我看到一个 Constant Scan
(Scan an internal table of constants)运算符而不是 Clustered Index Scan
之前 Segment
和 Stream 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/