Cas*_*jne 7 t-sql sql-server sql-server-2008
我不太明白为什么这两个不同的代码示例会返回不同的值.
以某种方式不正确但工作语法,返回错误结果,例如,0当比较在两个相等的值上完成时返回:
(SELECT CASE
WHEN
SUM(V.IsCompatible) OVER
(PARTITION BY ComputerName, UserID) = ApplicationCount
THEN 1 ELSE 0 END
) AS CompatibleUser
Run Code Online (Sandbox Code Playgroud)
下面的那个返回正确的值,即.1当比较两个相等的值时.
(CASE
WHEN
SUM(V.IsCompatible) OVER
(PARTITION BY ComputerName, UserID) = ApplicationCount
THEN 1 ELSE 0 END
) AS CompatibleUser
Run Code Online (Sandbox Code Playgroud)
甚至更简单:
(SELECT CASE
WHEN
X = Y
THEN 1 ELSE 0 END
) AS Result
Run Code Online (Sandbox Code Playgroud)
X = 22且Y = 22 =>结果= 0
(CASE
WHEN
X = Y
THEN 1 ELSE 0 END
) AS Result
Run Code Online (Sandbox Code Playgroud)
X = 22且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
Run Code Online (Sandbox Code Playgroud)
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(扫描一个常量的内部表)运算符而不是Clustered Index Scanbefore 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;
Run Code Online (Sandbox Code Playgroud)
结果:
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
Run Code Online (Sandbox Code Playgroud)