2010-07-13 3 views
10

Нужна помощь с пунктом поворота в SQL Server 2008. У меня есть таблица с этой информацией:SQL Pivot с несколькими столбцами

 
Weekno DayOfWeek  FromTime ToTime 
1   2    10:00  14:00 
1   3    10:00  14:00 
2   3    08:00  13:00 
2   4    09:00  13:00 
2   5    14:00  22:00 
3   1    06:00  13:00 
3   4    06:00  13:00 
3   5    14:00  22:00 

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

 
Week Start1 End1 Start2 End2 Start3 End3 Start4 End4 Start5 End5 Start6 End6 Start7 End7 
1       10:00  14:00 10:00  14:00 
2           08:00  13:00 09:00  13:00 14:00  22:00 
3  06:00  13:00          06:00  13:00 14:00  22:00 

Есть ли способ сделать с помощью сводного запроса? Пожалуйста, напишите ответьте на пример о том, как это сделать.

Я ценю любую помощь по этому вопросу. Заранее спасибо.

+0

Возможный дубликат [Несколько столбцов столбца в T-SQL] (http://stackoverflow.com/questions/947281/multiple-column-pivot-in-t-sql) –

ответ

8

Я лично ненавижу стержни - трудно читать и неумолимо.

CREATE TABLE #test 
(
    WeekNo int, 
    [DayOfWeek] int, 
    FromTime time, 
    ToTime time 
    ) 

INSERT INTO #test 
SELECT 1,2,'10:00','14:00' 
UNION ALL 
SELECT 1,3,'10:00','14:00' 
UNION ALL 
SELECT 2,3,'08:00','13:00' 
UNION ALL 
SELECT 2,4,'09:00','13:00' 
UNION ALL 
SELECT 2,5,'14:00','22:00' 
UNION ALL 
SELECT 3,1,'06:00','13:00' 
UNION ALL 
SELECT 3,4,'06:00','13:00' 
UNION ALL 
SELECT 3,5,'14:00','22:00' 

SELECT WeekNo, 
    MAX(CASE WHEN DayOfWeek = 1 THEN FromTime ELSE NULL END) AS Start1, 
    MAX(CASE WHEN DayOfWeek = 1 THEN ToTime ELSE NULL END) AS End1, 
    MAX(CASE WHEN DayOfWeek = 2 THEN FromTime ELSE NULL END) AS Start2, 
    MAX(CASE WHEN DayOfWeek = 2 THEN ToTime ELSE NULL END) AS End2, 
    MAX(CASE WHEN DayOfWeek = 3 THEN FromTime ELSE NULL END) AS Start3, 
    MAX(CASE WHEN DayOfWeek = 3 THEN ToTime ELSE NULL END) AS End3, 
    MAX(CASE WHEN DayOfWeek = 4 THEN FromTime ELSE NULL END) AS Start4, 
    MAX(CASE WHEN DayOfWeek = 4 THEN ToTime ELSE NULL END) AS End4, 
    MAX(CASE WHEN DayOfWeek = 5 THEN FromTime ELSE NULL END) AS Start5, 
    MAX(CASE WHEN DayOfWeek = 5 THEN ToTime ELSE NULL END) AS End5, 
    MAX(CASE WHEN DayOfWeek = 6 THEN FromTime ELSE NULL END) AS Start6, 
    MAX(CASE WHEN DayOfWeek = 6 THEN ToTime ELSE NULL END) AS End6, 
    MAX(CASE WHEN DayOfWeek = 7 THEN FromTime ELSE NULL END) AS Start7, 
    MAX(CASE WHEN DayOfWeek = 7 THEN ToTime ELSE NULL END) AS End7 
    FROM #test 
    GROUP BY WeekNo 

И это ударит носки с шарнира; эффективность.

+0

Выглядит как ничья между двумя подходами производительности мудрый. –

+0

@ Мартин Смит - У меня сначала должен быть UNPIVOT. Из-за этого я бы подумал, что традиционный «поворот» был бы быстрее. –

+0

Невозможно сказать на основе этого набора данных; необходимо будет создать некоторые большие тестовые данные. Даже с этими крошечными данными перекрестная вкладка работает лучше (0мс против 6 мс). Но проверьте планы исполнения, если вы заинтересованы в различиях. –

15

Вот версия поворота:

https://data.stackexchange.com/stackoverflow/query/7295/so3241450

-- SO3241450 

CREATE TABLE #SO3241450 (
    Weekno int NOT NULL 
    ,DayOfWeek int NOT NULL 
    ,FromTime time NOT NULL 
    ,ToTime time NOT NULL 
) 

INSERT INTO #SO3241450 VALUES 
(1, 2, '10:00', '14:00') 
,(1, 3, '10:00', '14:00') 
,(2, 3, '08:00', '13:00') 
,(2, 4, '09:00', '13:00') 
,(2, 5, '14:00', '22:00') 
,(3, 1, '06:00', '13:00') 
,(3, 4, '06:00', '13:00') 
,(3, 5, '14:00', '22:00') 

;WITH Base AS (
    SELECT Weekno, DayOfWeek, FromTime AS [Start], ToTime AS [End] 
    FROM #SO3241450 
) 
,norm AS (
SELECT Weekno, ColName + CONVERT(varchar, DayOfWeek) AS ColName, ColValue 
FROM Base 
UNPIVOT (ColValue FOR ColName IN ([Start], [End])) AS pvt 
) 
SELECT * 
FROM norm 
PIVOT (MIN(ColValue) FOR ColName IN ([Start1], [End1], [Start2], [End2], [Start3], [End3], [Start4], [End4], [Start5], [End5], [Start6], [End6], [Start7], [End7])) AS pvt​ 
+0

+1 для показа сводной версии –

+1

Абсолютно блестящий! Теперь я могу поворачивать и отображать столько столбцов, сколько хочу. Спасибо! Я бы предостерег об этом, сказав, что во время процесса UnPivot (до поворота в конце) все столбцы выбрасываются в один столбец. Это хорошо для этого примера, но если вы смешиваете числа, даты и строки, я бы предложил бросить все как VarChar, чтобы избежать ошибок (а затем при необходимости возвращаться к их исходным типам данных). – MikeTeeVee

0

Я думаю, что случай, когда будут работать только тогда, когда есть только уникальное Weekno и DAYOFWEEK, как он будет возвращать только записи последнего начала и окончания и отфильтруйте остальные. Пример

Weekno DayOfWeek  FromTime ToTime 
1   2    10:00  14:00 
1   2    07:00  09:00 
2   3    08:00  13:00 
2   4    09:00  13:00 

Это будет возвращать только первый ряд weekno 1 DAYOFWEEK 2 и пропустить вторую строку.

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