2013-10-03 5 views
1

У меня есть таблица (SQL Server 2008) с поставками, поэтому «Этап 0» означает «Новая отгрузка» и последовательные этапы - это разные этапы отслеживания отгрузки.Сводная таблица в SQL-Server 2008

Я пытаюсь повернуть следующую таблицу:.

CREATE TABLE TableName 
    ([ID] int, [IDShip] int, [Date] datetime, [Stage] int, [Arg] int) 
; 

INSERT INTO TableName 
    ([ID], [IDShip], [Date], [Stage], [Arg]) 
VALUES 
    (1, 1, '2013-10-03 08:36:00', 0, Null), 
    (2, 1, '2013-10-03 08:37:25', 1, 1), 
    (3, 2, '2013-10-03 08:38:25', 0, Null), 
    (4, 1, '2013-10-03 08:39:25', 2, 1), 
    (5, 2, '2013-10-03 08:40:25', 1, 3) 
; 

("Арг" является идентификатор Stage0 SELECT * будет :)

ID IDShip Date    Stage Arg 
1 1  2013-10-03 08:36:00  0 Null 
2 1  2013-10-03 08:37:25  1  1 
3 2  2013-10-03 08:38:25  0 Null 
4 1  2013-10-03 08:39:25  2  1 
5 2  2013-10-03 08:40:25  1  3 

во что-то вроде:

ID0 IDShip DateShipment   ID1 DateFirstStage  ID2 DateSecondStage 
1 1  2013-10-03 08:36:00 2 2013-10-03 08:37:25 4 2013-10-03 08:39:25  
3 2  2013-10-03 08:38:25 5 2013-10-03 08:40:25 

Любая помощь? Благодаря

+0

Благодарим за предоставление схемы! –

ответ

1

Оказалось немного более грязный, чем я надеялся, но вот это:

SELECT MAX([0]) AS ID0, 
    IDShip, 
    (SELECT [Date] FROM TableName T1 WHERE T1.ID = MAX([0]) AND T1.IDShip = Y.IDShip) AS DateShipment, 
    MAX([1]) AS ID1, 
    (SELECT [Date] FROM TableName T2 WHERE T2.ID = MAX([1]) AND T2.IDShip = Y.IDShip) AS DateFirstStage, 
    MAX([2]) AS ID2, 
    (SELECT [Date] FROM TableName T3 WHERE T3.ID = MAX([2]) AND T3.IDShip = Y.IDShip) AS DateSecondStage 
FROM 
    (SELECT * FROM TableName 
    PIVOT (MAX([ID]) FOR Stage IN ([0], [1], [2])) AS X) Y 
GROUP BY IDShip 

Вы первый поворотный стол в корочки 3 этапа и затем выберите каждый этап и его дату.

0

Похоже, что вам нужно одновременно поворачивать более одного столбца. Тем не менее, стандартный синтаксис PIVOT не поддерживает многоколоночное поворот. Вы можете использовать его для поворота одного из столбцов, а затем, используя эти значения в качестве исходных значений, вытащите другие значения столбца с помощью ряда коррелированных подзапросов.

Мой подход был похож на @ Szymon's, за исключением того, что мне удалось избежать группировки во внешнем запросе, хотя я делал вещи более грязными на других этапах. Вот моя попытка:

SELECT 
    IDShip, 
    ID0, 
    ID1, 
    ID2, 
    DateShipment = (SELECT Date FROM TableName WHERE ID = p.ID0), 
    DateFirstStage = (SELECT Date FROM TableName WHERE ID = p.ID1), 
    DateSecondStage = (SELECT Date FROM TableName WHERE ID = p.ID2) 
FROM (
    SELECT 
    ID, 
    IDShip, 
    StageID = 'ID' + CAST(Stage AS varchar(10)) 
    FROM TableName 
) AS s 
PIVOT (
    MAX(ID) FOR StageID IN (ID0, ID1, ID2) 
) AS p 
; 

При правильной индексации, это не может быть слишком плохо, хотя вы могли бы также попробовать эту альтернативу, которая использует старую технику поворотной группировки с условной агрегацией:

SELECT 
    IDShip, 
    ID0 = MAX(CASE Stage WHEN 0 THEN ID END), 
    ID1 = MAX(CASE Stage WHEN 1 THEN ID END), 
    ID2 = MAX(CASE Stage WHEN 2 THEN ID END), 
    DateShipment = MAX(CASE Stage WHEN 0 THEN Date END), 
    DateFirstStage = MAX(CASE Stage WHEN 1 THEN Date END), 
    DateSecondStage = MAX(CASE Stage WHEN 2 THEN Date END) 
FROM TableName 
GROUP BY IDShip 
; 

This SQL Fiddle demo позволит вам попробовать оба решения.

Смежные вопросы