我之前尝试过使用更具体的查询,但我想用一个非常简单的理论查询来分解它,以问为什么。
当第二个表t2由于where条件而没有填充时,case语句就会崩溃。
假设tblA只有一行
这将起作用:返回1
DECLARE @numA int SET @numA=1
DECLARE @numB int SET @numB=1
DECLARE @numC int SET @numC=2
SELECT
CASE WHEN(t1.v1=1 or t2.v2=1)
THEN 1
ELSE 0
END AS Test1
FROM
(SELECT 1 as v1
FROM tblA
WHERE @numA=@numB) t1,
(SELECT 0 as v2
FROM tblA
WHERE @numA<>@numC) t2
这不起作用,因为t2不会填充:
DECLARE @numA int SET @numA=1
DECLARE @numB int SET @numB=1
DECLARE @numC int SET @numC=2
SELECT
CASE WHEN(t1.v1=1 or t2.v2=1)
THEN 1
ELSE 0
END AS Test1
FROM
(SELECT 1 as v1
FROM tblA
WHERE @numA=@numB) t1,
(SELECT 0 as v2
FROM tblA
WHERE @numA=@numC) t2
我怎样才能做到这一点!?谢谢你们,我试过了
答案 0 :(得分:1)
你有一个交叉连接,一边返回0行。组合时返回0行。考虑一下:
SELECT a = 1 WHERE 1 = 1;
结果:
a
----
1
现在考虑结果返回0行的情况:
SELECT a = 1 WHERE 1 = 2;
结果:
a
----
现在,他们暗中交叉加入他们:
SELECT * FROM
(SELECT a = 1 WHERE 1 = 1) AS t1,
(SELECT a = 1 WHERE 1 = 2) AS t2;
或明确地说:
SELECT * FROM
(SELECT a = 1 WHERE 1 = 1) AS t1
CROSS JOIN
(SELECT a = 2 WHERE 1 = 2) AS t2;
在这两种情况下,您都得到零行,因为交叉连接的概念是“从一侧获取每一行,并为另一侧的每一行生成一行”。由于一侧没有行,因此没有行,句点。这就像乘以任意数字* 0.如果源是1或50或6000无关紧要,则该数字乘以零仍为零。所以更进一步:
SELECT a = CASE WHEN t1.a = 1 THEN 1 ELSE 0 END
FROM
(SELECT a = 1 WHERE 1 = 1) AS t1
CROSS JOIN
(SELECT a = 2 WHERE 1 = 2) AS t2;
这仍然会产生0行,因此CASE
表达式无法生成任何内容。也许你的意思是这样的:
SELECT a = CASE WHEN t1.a = 1 OR t2.a = 1 THEN 1 ELSE 0 END FROM
(SELECT a = 1 WHERE 1 = 1) AS t1
FULL OUTER JOIN
(SELECT a = 2 WHERE 1 = 2) AS t2
ON 1 = 1;
但是,我必须同意这些意见。为什么不让我们教你如何解决你想要解决的真正问题,而不是编造无意义的查询以试图理解行为?