将行展平为两列(如偶数和奇数),几乎像一个枢轴,但按另一列分组

问题描述 投票:0回答:1

我有一种情况,我的数据是

#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
sql-server t-sql pivot
1个回答
0
投票

我相信这符合所需的输出。请注意,此方法需要通过

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)
© www.soinside.com 2019 - 2024. All rights reserved.