当一个选择查询未填充时,Case语句不会返回值

时间:2013-12-11 16:06:16

标签: sql sql-server case

我之前尝试过使用更具体的查询,但我想用一个非常简单的理论查询来分解它,以问为什么。

当第二个表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

我怎样才能做到这一点!?谢谢你们,我试过了

1 个答案:

答案 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;

但是,我必须同意这些意见。为什么不让我们教你如何解决你想要解决的真正问题,而不是编造无意义的查询以试图理解行为?