2010-07-13 35 views
10

necesita ayuda con la cláusula de pivote en SQL Server 2008. Tengo una tabla con esta información:pivote SQL con varias columnas

 
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 

quiero convertir esto en una tabla que tiene este aspecto:

 
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 

¿Hay alguna manera de hacer con una consulta de pivote? Por favor escriba responder con un ejemplo sobre cómo hacerlo.

Agradezco cualquier tipo de ayuda en esto. Gracias por adelantado.

+0

posible duplicado de [Pivote de columna múltiple en T-SQL] (http://stackoverflow.com/questions/947281/multiple-column-pivot-in-t-sql) –

Respuesta

8

Personalmente odio los pivotes, difíciles de leer y sin previo aviso.

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 

Y volará los calcetines de un pivote; En cuanto al rendimiento.

+0

Parece un empate entre el rendimiento de dos enfoques sabio. –

+0

@Martin Smith - El mío tiene que DESVÍO primero. Por eso, pensé que el tradicional "pivote" hubiera sido más rápido. –

+0

Realmente no puedo decir basado en este conjunto de datos; necesitaría crear algunos datos de prueba grandes. Incluso con estos pequeños datos, la tabla cruzada tiene un mejor rendimiento (0 ms frente a 6 ms). Pero revisa los planes de ejecución si te interesan las diferencias. –

15

Aquí está la versión de pivote:

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 para mostrar la versión de pivote –

+1

¡Absolutamente brillante! Ahora puedo pivotar y mostrar tantas columnas como quiera. ¡Gracias! Quisiera advertir esto diciendo que durante el proceso de UnPivot (antes de pivotar al final) todas las columnas se arrojan a una sola columna. Esto está bien para este ejemplo, pero si está mezclando números, fechas y cadenas, sugeriría enviar todo como VarChar para evitar errores (y luego volver a sus tipos de datos originales si fuera necesario). – MikeTeeVee

0

creo que el caso cuando sólo funcionará si hay solamente es único Weekno y DayofWeek ya que sólo devolverá los registros de última hora de inicio y fin y filtra el resto. Ejemplo

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 

Es sólo devolverá la primera fila de weekno 1 de DayofWeek 2 y omita la segunda fila.

Cuestiones relacionadas