Конвертировать строки в столбцы - PullRequest
2 голосов
/ 24 ноября 2010

У меня есть следующая структура:

Emp  PayDate       Amount    
1    11/23/2010    500    
1    11/25/2010    -900    
1    11/28/2010    1000    
1    11/29/2010    2000    
2    11/25/2010    2000    
3    11/28/2010    -3000    
2    11/28/2010    4000    
3    11/29/2010    -5000

Мне нужно получить следующий результат, если выбран emp 1 (верхние 3 даты и соответствующие им значения - если они существуют - 4-я строка всегда игнорируется)

PayDate1     Amount1   Paydate2     Amount2   Paydate3    Amount3
11/23/2010   500       11/25/2010   -900      11/28/2010  1000

Мне нужно получить следующий результат, если выбран emp 2

Paydate1    Amount1   Paydate2     Amount2   Paydate3 Amount3
11/25/2010  2000      11/28/2010   4000      NULL     NULL

Мне нужно получить следующий результат, если выбран emp 3

Paydate1       Amount1   Paydate2      Amount2   Paydate3   Amount3
11/28/2010    -3000      11/29/2010    -5000

Чтобы получить соответствующие данные в строках, я могу выполнить следующий запрос:

select top 3 Paydate, Amount from Table where Emp = @Emp

Но как мне получить результат в развернутом виде?

Ответы [ 2 ]

1 голос
/ 24 ноября 2010

Отличная статья о Pivots с SQL Server 2005+ здесь .

0 голосов
/ 25 ноября 2010
CREATE TABLE dbo.Table1 
(
    Emp        int,
    PayDate    datetime,
    Amount     int
)
GO

INSERT INTO dbo.Table1 VALUES (1, '11/23/2010',500)
INSERT INTO dbo.Table1 VALUES (1, '11/25/2010',-900)
INSERT INTO dbo.Table1 VALUES (1, '11/28/2010',1000)
INSERT INTO dbo.Table1 VALUES (1, '11/29/2010',2000)
INSERT INTO dbo.Table1 VALUES (2, '11/25/2010',2000)
INSERT INTO dbo.Table1 VALUES (3, '11/28/2010',-3000)
INSERT INTO dbo.Table1 VALUES (2, '11/28/2010',4000)
INSERT INTO dbo.Table1 VALUES (3, '11/29/2010',-5000)


;WITH cte AS
(SELECT Emp, PayDate, Amount, PayDateRowNumber
FROM 
(SELECT Emp,
       PayDate,
       Amount,
       ROW_NUMBER() OVER (PARTITION BY Emp ORDER BY PayDate) AS PayDateRowNumber
FROM Table1) AS RankedTable1
WHERE PayDateRowNumber < 4)
SELECT c1.Emp AS Emp, c1.PayDate AS PayDate1
        ,c1.Amount AS Amount1, c2.PayDate AS PayDate2
        ,c2.Amount AS Amount2, c3.PayDate AS PayDate3, c3.Amount AS Amount3
FROM cte c1
LEFT JOIN cte c2 ON c2.Emp = c1.Emp AND c2.PayDateRowNumber = 2
LEFT JOIN cte c3 ON c3.Emp = c2.Emp AND c3.PayDateRowNumber = 3
WHERE c1.PayDateRowNumber = 1

Вывод:

alt text

Некоторые оговорки заключаются в том, что он не будет агрегировать суммы для одного и того же работодателя / даты (хотя его можно легко изменить). Также может потребоваться изменить использование ROW_NUMBER () по сравнению с RANK () и DENSE_RANK () в зависимости от вашего определения «TOP 3»

...