2016-07-21 11 views
0

Ich habe eine Table wie unten.UNPIVOT in SQL-Server ohne Aggregat

OfficeID SunFrom SunTo MonFrom MonTo TueFrom TueTo WedFrom WedTo ThuFrom ThuTo FriFrom FriTo SatFrom SatTo 
51834  12  17  8  22  8  22  8  22  8  22  9  21  8  19 

Ich brauche diese Tabelle die Spalte in

Zeilen konvertieren

Erwartete Ausgabe:

Officeid Day   Daystart DayEnd 

51834  Sunday  12   17 
51834  Monday  8   22 
51834  Tuesday  8   22 
51834  Wednesday 8   22 
51834  Thursday 8   22 
51834  Friday  9   21 
51834  Saturday 8   19 

Ich habe versucht, mit UNPIVOT aber ich bin nicht sicher, welche Spalte ich als pivot column wählen müssen. Bitte helfen Sie.

+1

Ich denke, der beste Weg, 7 Abfragen auszuführen ist, jede Abfrage für einen Tag der Woche. Wenn dies eine Routineaufgabe ist, können Sie eine gespeicherte Prozedur erstellen oder eine dynamische Abfrage verwenden. – DVT

Antwort

1

Dies wird den größten Teil des Weges dorthin. Wenn Sie einen bestimmten Ausgabeauftrag wünschen, würde ich vorschlagen, eine Hilfstabelle, die den 3-Zeichen-Tag-Namen zu einem Sortier-Index abbildet (und den vollen Länge Namen, falls gewünscht):

declare @t table (OfficeID int,SunFrom int,SunTo int,MonFrom int,MonTo int, 
TueFrom int,TueTo int,WedFrom int,WedTo int, 
ThuFrom int,ThuTo int,FriFrom int,FriTo int, 
SatFrom int,SatTo int) 
insert into @t(OfficeID,SunFrom,SunTo,MonFrom,MonTo,TueFrom,TueTo, 
WedFrom,WedTo,ThuFrom,ThuTo,FriFrom,FriTo,SatFrom,SatTo) values 
(51834,12,17,8,22,8,22,8,22,8,22,9,21,8,19) 

select 
    OfficeID,Day, 
     MAX(CASE WHEN Endpoint='From' THEN EndpointTime END) as Daystart, 
     MAX(CASE WHEN Endpoint='To' THEN EndpointTime END) as DayEnd 
from 
    @t t 
     unpivot 
    (EndpointTime for DayAndEndPoint in (SunFrom,SunTo,MonFrom,MonTo,TueFrom,TueTo, 
WedFrom,WedTo,ThuFrom,ThuTo,FriFrom,FriTo,SatFrom,SatTo)) a 
     cross apply 
    (select SUBSTRING(DayAndEndpoint,1,3) as Day,SUBSTRING(DayAndEndpoint,4,4) as Endpoint) b 
group by 
    OfficeID,Day 

Ergebnis:

OfficeID Day Daystart DayEnd 
----------- ---- ----------- ----------- 
51834  Fri 9   21 
51834  Mon 8   22 
51834  Sat 8   19 
51834  Sun 12   17 
51834  Thu 8   22 
51834  Tue 8   22 
51834  Wed 8   22 

Wie Sie hoffentlich wissen, wäre es, wenn möglich, besser, Ihre Datenbank so neu zu gestalten, dass sie dem Ergebnissatz ähnlicher ist als das Original - Daten desselben "Typs" sollten in einer einzigen Spalte stehen und Daten sollten modelliert werden als Daten anstatt in Spaltennamen eingebettet werden.


Erweiterte Variante, wenn Ausgabereihenfolge und Tagesnamen besonders wichtig sind:

declare @t table (OfficeID int,SunFrom int,SunTo int,MonFrom int,MonTo int, 
TueFrom int,TueTo int,WedFrom int,WedTo int, 
ThuFrom int,ThuTo int,FriFrom int,FriTo int, 
SatFrom int,SatTo int) 
insert into @t(OfficeID,SunFrom,SunTo,MonFrom,MonTo,TueFrom,TueTo, 
WedFrom,WedTo,ThuFrom,ThuTo,FriFrom,FriTo,SatFrom,SatTo) values 
(51834,12,17,8,22,8,22,8,22,8,22,9,21,8,19) 

declare @DayNameAndSort table (Day varchar(3) not null,ExtendedName varchar(19) not null,SortOrder int not null) 
insert into @DayNameAndSort (Day,ExtendedName,SortOrder) values 
('Fri','Friday', 5), 
('Mon','Monday', 1), 
('Sat','Saturday', 6), 
('Sun','Sunday', 0), 
('Thu','Thursday', 4), 
('Tue','Tuesday', 2), 
('Wed','Wednesday',3) 


;With ReOriented as (
select 
    OfficeID,Day, 
     MAX(CASE WHEN Endpoint='From' THEN EndpointTime END) as Daystart, 
     MAX(CASE WHEN Endpoint='To' THEN EndpointTime END) as DayEnd 
from 
    @t t 
     unpivot 
    (EndpointTime for DayAndEndPoint in (SunFrom,SunTo,MonFrom,MonTo,TueFrom,TueTo, 
WedFrom,WedTo,ThuFrom,ThuTo,FriFrom,FriTo,SatFrom,SatTo)) a 
     cross apply 
    (select SUBSTRING(DayAndEndpoint,1,3) as Day,SUBSTRING(DayAndEndpoint,4,4) as Endpoint) b 
group by 
    OfficeID,Day 
) 
select 
    OfficeID,ExtendedName,Daystart,DayEnd 
from 
    ReOriented r 
     inner join 
    @DayNameAndSort s 
     on 
      r.Day = s.Day 
order by s.SortOrder 
+0

danke damien..Aber es ist möglich, Tag Id statt Tagname zurückzugeben? wie 1 für Sonne, 2 für Mon? – bmsqldev

+0

@bmsqldev - Sie sollten in der Lage sein, meine zweite Version anzupassen, die eine Zusatztabelle verwendet, um zusätzliche Informationen über die Tage einzubringen. –