TSQL-折叠匹配记录
代码: 查询:TSQL-折叠匹配记录,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,代码: 查询: 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
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
目标:折叠键列上匹配的两行,并获得每个
案例
语句列的输出,而不是两个单独的列。注意,在real query中,这些表很大,我加入了其他几个表,并选择了更多的描述性列。此查询必须具有最小读取/快速!(即,如果可能,不能使用临时表/变量/CTE和全部)您只需要一个聚合函数:
ID1 SD ED
---------------------------
1 2016-09-01 2016-08-31
2 NULL NULL
如果要避免分组方式
,只要@T2
中没有重复的行,就可以进行两次左联接:
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;
您的表设计将决定查询样式以实现您的目标。因为您选择了GROUPBY,所以其他选项肯定会涉及自表联接和各种其他选项。最佳解决方案应基于以下内容:
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;
无论如何,要避免GROUP BY/DISTINCT?假设@T2上没有重复项,您可以使用适当的条件进行两次左连接hanks!我曾想过使用2个左连接路由,但@t2是一个巨大的表,我不确定是否要这样做……除非这是最快的方法。@Lamak不需要子查询。可以将条件移动到on段。它会短得多。@Hamawi,我知道,但为了可读性,我更喜欢这样,优化器很可能会生成相同的执行计划“无法使用临时表/变量/CTE”。。。那么,你能用什么呢?您知道SQL Server可能会选择在后台构建临时表,即使您没有显式地这样做,对吗?除非要在同一数据库中执行
选择进入
,否则将使用tempdb,并在执行过程中跨越进程边界。此外,请澄清您是希望汇总,还是仅仅表示所有组合-即,如果您有“2016-01-01”和“2016-01-02”的SD
,您是否希望同时看到这两种组合?
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