JOIN 中的 SQL CASE 语句 - 当其他表中的值存在时
Posted
技术标签:
【中文标题】JOIN 中的 SQL CASE 语句 - 当其他表中的值存在时【英文标题】:SQL CASE statement in JOIN - when value in other table exists 【发布时间】:2018-03-01 12:50:59 【问题描述】:我有桌子 T1
TICKETID
1
2
我有桌子 T2
ID TICKETID STATUS
1 1 NEW
2 1 OPEN
3 1 CLOSED
4 2 NEW
5 2 OPEN
6 2 RETURNED
我想从 T1 中选择并与 T2 进行 JOIN,如果记录的状态曾经处于 RETURNED 状态,那么我需要有一个值“YES”,否则我需要有一个值“NO”
所以最终结果应该是
TICKETID RETURNED_FLAG
1 NO
2 YES
我尝试过类似的方法,但我不确定这是否是最佳的,甚至是正确的。
SELECT T1.TICKETID, CASE (T2.ID)
WHEN NULL THEN 'NO'
ELSE 'YES'
END FROM T1
LEFT OUTER JOIN T2 ON T1.TICKETID=T2.TICKETID AND T2.STATUS='RETURNED'
【问题讨论】:
案例表达式,不是语句。 【参考方案1】:关闭。这是一种方法:
SELECT T1.TICKETID,
(CASE WHEN COUNT(T2.ID) THEN 'YES' ELSE 'NO' END) as flag
FROM T1 LEFT OUTER JOIN
T2
ON T1.TICKETID = T2.TICKETID AND T2.STATUS = 'RETURNED'
GROUP BY T1.TICKETID;
更典型的方式是:
select t1.*,
(case when exists (select 1
from t2
where t2.ticketid = t.ticketid and t2.status = 'RETURNED'
)
then 'YES' else 'NO'
end) as flag
from t1;
这应该有更好的性能,尤其是在t2(ticketid, status)
上的索引。
【讨论】:
【参考方案2】:如果每张票只能退一次,你也可以使用 DECODE 而不分组:
SELECT T1.TICKETID,
DECODE(T2.STATUS, 'RETURNED','YES','NO') as flag
FROM T1 LEFT OUTER JOIN T2
ON T1.TICKETID = T2.TICKETID AND T2.STATUS = 'RETURNED';
如果一个工单在 T2 中有多个 RETURNED 条目,这将导致该工单出现多个 YES 行。
【讨论】:
对我来说最好的建议【参考方案3】:试试这个:
SELECT TICKETID,
ISNULL((SELECT TOP(1) 'YES'
FROM T2
WHERE T1.TICKETID=T2.TICKETID AND T2.STATUS='STATUS'),
'NO') AS RETURN_FLAG
FROM T1;
【讨论】:
【参考方案4】:您的查询是正确的,但您的案例利用率不正确,您应该添加 distinct 以删除重复项:
SELECT distinct T1.TICKETID,
CASE WHEN T2.ID IS NULL THEN 'NO' ELSE 'YES' END FROM T1
LEFT OUTER JOIN T2 ON T1.TICKETID=T2.TICKETID AND T2.STATUS='RETURNED'
这里的多种方法也不错,但对我来说,保持简单。
【讨论】:
以上是关于JOIN 中的 SQL CASE 语句 - 当其他表中的值存在时的主要内容,如果未能解决你的问题,请参考以下文章
Redshift 中的 update + case + join 语句