我有一种情况,我的数据是
#SourceData
表的格式,我需要将其转换为#FinalData
表的格式,示例代码如下。
稍微口头解释一下,
RowNumber
表的#SourceData
列是对日期进行排序的,按TrackingNumber
列分组。 RowNumber
列中具有奇数的日期将进入 Date1
,偶数的日期将进入 Date2
。
看起来它可能是一个
PIVOT
,但不完全是,它开始让我的大脑融化。 注意,一个 TrackingNumber(不包括在内)有超过 100 个日期。
示例数据:
CREATE Table #SourceData
(
TrackingNumber int NULL,
Date1 date NULL,
Date2 date NULL,
RowNumber int NULL
);
INSERT INTO #SourceData
SELECT 3 , '09/18/2016', NULL, 1
UNION SELECT 3 , '12/21/2016', NULL, 2
UNION SELECT 12 , '01/30/2018', NULL, 1
UNION SELECT 12 , '01/30/2018', NULL, 2
UNION SELECT 12 , '03/01/2019', NULL, 3
UNION SELECT 12 , '03/05/2019', NULL, 4
UNION SELECT 12 , '04/19/2020', NULL, 5
UNION SELECT 23 , '02/14/2017', NULL, 1
UNION SELECT 130 , '04/12/2017', NULL, 1
----------------------------------------
CREATE Table #FinalData
(
TrackingNumber int NULL,
Date1 date NULL,
Date2 date NULL
);
INSERT INTO #FinalData
SELECT 3 , '09/18/2016', '12/21/2016'
UNION SELECT 12 , '01/30/2018', '01/30/2018'
UNION SELECT 12 , '03/01/2019', '03/05/2019'
UNION SELECT 12 , '04/19/2020', NULL
UNION SELECT 23 , '02/14/2017', NULL
UNION SELECT 130 , '04/12/2017', NULL
我相信这符合所需的输出。请注意,此方法需要通过
select distinct
减少行数,因此它可能不如第二种方法有效:
select distinct
TrackingNumber
, case when RowNumber % 2 > 0 then Date1
else lag(date1,1) over(partition by TrackingNumber order by RowNumber)
end as Date1
, case when RowNumber % 2 = 0 then Date1
else lead(date1,1) over(partition by TrackingNumber order by RowNumber)
end as Date2
from #SourceData
追踪号码 | 日期1 | 日期2 |
---|---|---|
3 | 2016-09-18 | 2016-12-21 |
12 | 2018-01-30 | 2018-01-30 |
12 | 2019-03-01 | 2019-03-05 |
12 | 2020-04-19 | 空 |
23 | 2017-02-14 | 空 |
130 | 2017-04-12 | 空 |
另一种性能可能更好的方法是使用外部应用:
select
d.TrackingNumber
, d.date1
, oa.Date2
, d.RowNumber
from #SourceData d
outer apply (
select s.date1
from #SourceData s
where s.TrackingNumber = d.TrackingNumber
and s.RowNumber = d.RowNumber + 1
) oa (Date2)
where d.RowNumber % 2 > 0
追踪号码 | 日期1 | 日期2 | 行号 |
---|---|---|---|
3 | 2016-09-18 | 2016-12-21 | 1 |
12 | 2018-01-30 | 2018-01-30 | 1 |
12 | 2019-03-01 | 2019-03-05 | 3 |
12 | 2020-04-19 | 空 | 5 |
23 | 2017-02-14 | 空 | 1 |
130 | 2017-04-12 | 空 | 1 |
请注意,第二个中包含 RowNumber 纯粹是为了证明此方法确实处理更少的行。另请注意,如果外部应用按如下方式修改,您还可以输出两个 RowNumber(s):
outer apply (
select s.date1, s.RowNumber
from #SourceData s
where s.TrackingNumber = d.TrackingNumber
and s.RowNumber = d.RowNumber + 1
) oa (Date2, RowNumber2)