2010-07-13 27 views
10

Benötigen Sie mit der Pivot-Klausel in SQL Server helfen 2008. Ich habe eine Tabelle mit dieser Info:SQL Pivot mit mehreren Spalten

 
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 

Ich möchte diese in eine Tabelle konvertieren, die wie folgt aussieht:

 
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 

Gibt es eine Möglichkeit mit einer Pivot-Abfrage zu tun? Bitte schreiben Sie antworten mit einem Beispiel, wie es geht.

Ich schätze jede Art von Hilfe zu diesem Thema. Danke im Voraus.

+0

mögliche Duplikate von [Mehrere Spalten Pivot in T-SQL] (http://StackOverflow.com/Questions/947281/Multiple-Column-Pivot-in-T-SQL) –

Antwort

8

Ich persönlich hasse pivots - schwer zu lesen und unweidly.

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 

Und es wird die Socken von einem Drehpunkt blasen; Leistung weise.

+0

Sieht aus wie ein Unentschieden zwischen den beiden Ansätze Leistung weise. –

+0

@Martin Smith - Mine muss zuerst UNPIVOT. Aus diesem Grund hätte ich gedacht, dass der traditionelle "Pivot" schneller gewesen wäre. –

+0

Kann aufgrund dieses Datensatzes nicht wirklich sagen; müsste einige große Testdaten erstellen. Selbst mit diesen winzigen Daten funktioniert die Kreuzlasche besser (0 ms vs 6 ms). Aber schauen Sie sich die Ausführungspläne an, wenn Sie an den Unterschieden interessiert sind. –

15

Hier ist die Pivot-Version:

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 für die Pivot-Version –

+1

Absolut Brilliant! Ich kann jetzt beliebig viele Spalten drehen und anzeigen. Vielen Dank! Ich würde dies mit dem Vorbehalt bestrafen, dass während des UnPivot-Prozesses (vor dem Pivotieren am Ende) alle Spalten in eine einzelne Spalte geworfen werden. Dies ist für dieses Beispiel in Ordnung, aber wenn Sie Zahlen, Daten und Strings mischen, würde ich vorschlagen, alles als VarChar zu interpretieren, um Fehler zu vermeiden (und dann bei Bedarf auf ihre ursprünglichen Datentypen zurückzuspringen). – MikeTeeVee

0

denke ich, der Fall, wenn nur, wenn es funktioniert nur einzigartige Weekno und DAYOFWEEK sind, da es nur Aufzeichnungen neuesten Start- und Endzeit zurückkehren und filtere den Rest heraus. Beispiel

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 wird nur die erste Zeile von weekno 1 von DAYOFWEEK 2 zurück und die zweite Reihe überspringen.

Verwandte Themen