我有以下两个表:
T1
Id Value
NULL A
NULL B
NULL C
T2
Id Value
1 A
2 C
-2 Unmatched
我想使用CASE
表达式加入Value,t1中所有在t2中都有相应行的行。对于那些不匹配的我想要默认为不匹配的行(-2)。我的预期输出是:
t1.Id t1.Value t2.Id t2.Value
NULL A 1 A
NULL B -2 Unmatched
NULL C 2 C
但是使用以下脚本:
WITH t1
AS
(
SELECT NULL AS Id,
'A' AS Value
UNION ALL
SELECT NULL AS Id,
'B' AS Value
UNION ALL
SELECT NULL AS Id,
'C' AS Value
),
t2
AS
(
SELECT 1 AS Id,
'A' AS Value
UNION ALL
SELECT 2 AS Id,
'C' AS Value
UNION ALL
SELECT -2 AS Id,
'Not Matched' AS Value
)
SELECT *
FROM t1
LEFT OUTER JOIN t2
ON (CASE
WHEN t1.Value = t2.Value
THEN t2.Id
WHEN t1.Value IS NOT NULL
THEN -2
END) = t2.Id;
我得到以下结果:
t1.Id t1.Value t2.Id t2.Value
NULL A 1 A
NULL A -2 Unmatched
NULL B -2 Unmatched
NULL C 2 C
NULL C -2 Unmatched
我有一个简单的解决方法,可以做我需要的但是我的问题是为什么我似乎在我的案例表达式中得到这种行为?删除第二个WHEN
会产生以下内容,这几乎符合要求:
t1.Id t1.Value t2.Id t2.Value
NULL A 1 A
NULL B NULL NULL
NULL C 2 C
答案 0 :(得分:2)
要回答你的问题,即使它有其他匹配,每一行都匹配-2行。如果我简化ON子句只显示-2匹配,那就很清楚了:
SELECT *
FROM t1
JOIN t2
ON CASE WHEN t1.Value IS NOT NULL THEN -2 END = t2.Id;
答案 1 :(得分:0)
正如JBrooks在他的回答中指出的那样,你的WHEN t1.Value IS NOT NULL将永远为真(因为t1.Value永远不会为NULL,因为这是你的连接的左侧)。
完全删除WHEN,而只是在select语句中执行ISNULL或COALESCE。
WITH t1
AS
(
SELECT NULL AS Id,
'A' AS Value
UNION ALL
SELECT NULL AS Id,
'B' AS Value
UNION ALL
SELECT NULL AS Id,
'C' AS Value
),
t2
AS
(
SELECT 1 AS Id,
'A' AS Value
UNION ALL
SELECT 2 AS Id,
'C' AS Value
UNION ALL
SELECT -2 AS Id,
'Not Matched' AS Value
)
SELECT t1.id, t1.value, ISNULL(t2.id, -2), ISNULL(t2.value,'Unmatched')
FROM t1
LEFT OUTER JOIN t2 ON t1.value = t2.value
;
结果
NULL A 1 A
NULL B -2 Unmatched
NULL C 2 C