如何使用某些结果值作为列名来编写复杂的SQL Server数据透视表?

时间:2018-09-10 19:06:27

标签: sql pivot sql-server-2017

Microsoft SQL Server 2017

我试图编写一个数据透视图,以获取数据的各个行并将其合并到一个“平面”表中。这是示例数据的样子:

HeaderID    ChangeDateTime  DataQualifier       DataValue
12345       8/1/18 8:00 AM  ComponentComName    Com1
12345       8/1/18 8:00 AM  DriverNumber        Driver1
12345       8/1/18 11:00 AM DriverNumber        Driver2
12345       8/2/18 8:00 AM  EndProduct          End1
56789       8/1/18 9:30 AM  ComponentComName    Com2
56789       8/1/18 11:30 AM DriverNumber        Driver3
56789       8/2/18 8:00 AM  EndProduct          End2

我的最终目标是获得如下结果:

HeaderID    ChangeDateTime  HistoryEnd      ComName  Driver  EndProduct
12345   8/1/18 8:00         8/1/18 10:59    Com1     Driver1    
12345   8/1/18 11:00        12/31/76 12:00           Driver2    
12345   8/2/18 8:00         12/31/76 12:00                   End1
56789   8/1/18 9:30         12/31/76 12:00  Com2        
56789   8/1/18 11:30        12/31/76 12:00           Driver3    
56789   8/2/18 8:00         12/31/76 12:00                   End2

这是我到目前为止的代码,但没有得到期望的结果:

Declare @History Table
(
    HeaderID int,
    ChangeDateTime datetime,
    DataQualifier varchar(80),
    DataValue varchar(255)
);

-- Insert sample data
Insert Into @History
Values (12345, '2018-08-01 08:00', 'ComponentComName', 'Com1'),
(12345, '2018-08-01 08:00', 'DriverNumber', 'Driver1'),
(12345, '2018-08-01 11:00', 'DriverNumber', 'Driver2'),
(12345, '2018-08-02 08:00', 'EndProduct', 'End1'),
(56789, '2018-08-01 09:30', 'ComponentComName', 'Com2'),
(56789, '2018-08-01 11:30', 'DriverNumber', 'Driver3'),
(56789, '2018-08-02 08:00', 'EndProduct', 'End2');

With Attributes
As (Select ROW_NUMBER() Over (Partition By HeaderID Order By HeaderID) As RowID,
    convert(smalldatetime, ChangeDateTime) ChangeDateTime,
    coalesce(dateadd(s, -1, convert(datetime, convert(smalldatetime, LEAD(ChangeDateTime) OVER (PARTITION BY HeaderID, DataQualifier ORDER BY ChangeDateTime)))), CAST('2076-12-31 23:59:59.997' AS datetime)) 'HistoryEnd',
DataQualifier,
HeaderID,
DataValue
From @History)
Select HeaderID,
convert(smalldatetime, ChangeDateTime) ChangeDateTime,
HistoryEnd,
DataValue1 ComName, -- would like this to be dynamic so it names the column for me
DataValue2 Driver, -- would like this to be dynamic so it names the column for me
DataValue3 EndProduct -- would like this to be dynamic so it names the column for me
From (Select ROW_NUMBER() Over (Partition By HeaderID Order By HeaderID) As RowID,
    HeaderID,
    convert(smalldatetime, ChangeDateTime) ChangeDateTime,
    'Qualifier' + Cast(RowID as varchar) As QualifierNum,
    'DataValue' + Cast(RowID as varchar) As DataValueNum,
    DataQualifier,
    DataValue,
    HistoryEnd
From Attributes) As Pvt

Pivot (Min(DataQualifier)
For QualifierNum In ([Qualifier1], [Qualifier2], [Qualifier3])) As Pvt1

Pivot (Min(DataValue)
For DataValueNum In ([DataValue1], [DataValue2], [DataValue3])) As Pvt2;`

这是我得到的结果集:

HeaderID    ChangeDateTime  HistoryEnd  ComName Driver  EndProduct
12345   2018-08-01 08:00:00 2076-12-31 23:59:59.997 Com1    NULL    NULL
56789   2018-08-01 09:30:00 2076-12-31 23:59:59.997 Com2    NULL    NULL
12345   2018-08-01 08:00:00 2018-08-01 10:59:59.000 NULL    Driver1 NULL
56789   2018-08-01 11:30:00 2076-12-31 23:59:59.997 NULL    Driver3 NULL
12345   2018-08-01 11:00:00 2076-12-31 23:59:59.997 NULL    NULL    Driver2
56789   2018-08-02 08:00:00 2076-12-31 23:59:59.997 NULL    NULL    End2
12345   2018-08-02 08:00:00 2076-12-31 23:59:59.997 NULL    NULL    NULL

我显然不能正确地编码轴。有人可以指出我正确的方向吗?

0 个答案:

没有答案