代码:
DECLARE @T1 TABLE (ID1 INT);
DECLARE @T2 TABLE (ID1 INT, ID2 INT, DT DATE);
INSERT INTO @T1 (ID1)
VALUES (1), (2);
INSERT INTO @T2 (ID1, ID2, DT)
SELECT 1, 100, GETDATE()
UNION
SELECT 1, 200, GETDATE() - 1
UNION
SELECT 3, 300, GETDATE()
UNION
SELECT 4, 200, GETDATE();
查询:
SELECT
T1.ID1,
CASE
WHEN T2.ID2 = 100 THEN T2.DT
END SD,
CASE
WHEN T2.ID2 = 200 THEN T2.DT
END ED
FROM
@T1 T1
LEFT JOIN
@T2 T2 ON T1.ID1 = T2.ID1 AND T2.ID2 IN (100, 200);
当前输出:
ID1 SD ED
----------------------------
1 2016-09-01 NULL
1 NULL 2016-08-31
2 NULL NULL
期望的输出:
ID1 SD ED
---------------------------
1 2016-09-01 2016-08-31
2 NULL NULL
GOAL :折叠在键列上匹配的两行,并为每个CASE
语句列而不是2个单独的列输出输出。请注意,在实际查询中,这些表很大,我加入了一些其他表并选择了更多描述性列。此查询必须具有最小读数/快速! (即,如果可能的话,不能使用临时表/变量/ CTE)
答案 0 :(得分:2)
您只需要一个聚合函数:
SELECT T1.ID1 ,
MIN(CASE WHEN T2.ID2 = 100 THEN T2.DT
END) SD ,
MIN(CASE WHEN T2.ID2 = 200 THEN T2.DT
END) ED
FROM @T1 T1
LEFT JOIN @T2 T2 ON T1.ID1 = T2.ID1
AND T2.ID2 IN ( 100, 200 )
GROUP BY T1.ID1;
如果您想避免GROUP BY
,只要@T2
中没有重复的行,您就可以进行2次左连接:
SELECT T1.ID1 ,
T100.DT SD,
T200.DT ED
FROM @T1 T1
LEFT JOIN ( SELECT *
FROM @T2
WHERE ID2 = 100) T100
ON T1.ID1 = T100.ID1
LEFT JOIN ( SELECT *
FROM @T2
WHERE ID2 = 200) T200
ON T1.ID1 = T200.ID1;
答案 1 :(得分:1)
你需要使用PIVOT:
Select * from
(SELECT
T1.ID1, T2.DT,
CASE
WHEN T2.ID2 = 100 THEN 'SD'
WHEN T2.ID2 = 200 THEN 'ED'
END SDED
FROM
@T1 T1
LEFT JOIN
@T2 T2 ON T1.ID1 = T2.ID1 AND T2.ID2 IN (100, 200)) t
Pivot (MAX(DT) FOR SDED in ([SD], [ED]) ) P
答案 2 :(得分:0)
您的表格设计将决定实现目标的查询方式。因为,你选择了group by,其他选项肯定会涉及自我表连接和各种其他选项。最佳解决方案应基于以下内容: