2016-07-04 19 views
0

Hmm, nur den richtigen Titel zu bekommen dauerte 10 Minuten und ich bin mir nicht sicher, ob ich es meine Frage zu decken. Einige Hintergrundinformationen: Meine Tabelle enthält Sicherungsergebnisse von mehreren Servern. Der Einfachheit halber einige Zeilen nur für einen Server:SQL Server: Pivot auf mehreren Spalten

hostname type_id result_id received 
---------------------------------------- 
SBS2011  5  1  2016-06-28 
SBS2011  5  1  2016-06-28 
SBS2011  5  1  2016-06-29 
SBS2011  5  1  2016-06-29 
SBS2011  5  1  2016-06-30 
SBS2011  6  1  2016-06-30 
SBS2011  5  2  2016-07-01 
SBS2011  6  2  2016-07-01 
SBS2011  6  2  2016-07-01 
SBS2011  5  1  2016-07-02 
SBS2011  6  1  2016-07-02 
SBS2011  5  1  2016-07-03 
SBS2011  6  1  2016-07-03 
SBS2011  5  1  2016-07-04 
SBS2011  6  1  2016-07-04 

eine PIVOT verwenden kann ich einen Überblick über die Menge von Backups für jeden Wochentag erhalten:

select * from 
(
    select [hostname], [type_id], datepart(w, received) as workday from [backups] 
) TEMP 
pivot (
    count([type_id]) 
    for workday in 
    ([1], [2], [3], [4], [5], [6], [7]) 
) as pvt; 

Ergebnisse in:

hostname 1 2 3 4 5 6 7 
-------------------------------------- 
SBS2011  2 2 2 2 2 3 2 

Aber dieses Ergebnis vermisst einige wichtige Informationen. Als result_id ‚Erfolg‘ ist gleich und result_id ‚nicht bestanden‘ ist gleich, würde Ich mag das Ergebnis haben, wie folgt aussehen:

hostname 1:1 1:2 2:1 2:2 3:1 3:2 4:1 4:2 5:1 5:2 6:1 6:2 7:1 7:2 
------------------------------------------------------------------- 
SBS2011  2 0 2 0 2 0 2 0 2 0 0 3 2 0 

wo column 1: 1 ist eine Abkürzung für Sonntag: Erfolg und 1: 2 Sonntag gleich: gescheitert. Für einige Backup-Typ-IDs kann auch eine Spalte 1: 3 für Sonntag vorhanden sein: Wiederholen.

Als ich mich umsah, stellte ich fest, dass ein DYNAMIC PIVOT der Schlüssel zur Lösung dieses Rätsels sein könnte. Andere schlagen eine PARTITION vor, aber ich habe noch nicht herausgefunden, wie. Der DYNAMIC PIVOT scheint am vielversprechendsten zu sein, aber ich weiß nicht wie. Bitte helfen Sie mir diese für mich komplexe Abfrage zu erstellen?

Antwort

0

Wenn Sie einfach es statisch halten konnte nicht mit dynamischen SQL-Geige wollen und die Spalte ändern, die auf geschwenkt.

Eine Abfrage wie:

select * 
from 
(
    select 
     [hostname], 
     [type_id], 
     concat(datepart(w, received),':',result_id) as workday 
    from [backups] 
) TEMP 
pivot (
    count([type_id]) 
    for workday in (
     -- maybe you don't want the :3 option for all days? Adjust as needed 
     [1:1],[1:2],[1:3], 
     [2:1],[2:2],[2:3], 
     [3:1],[3:2],[3:3], 
     [4:1],[4:2],[4:3], 
     [5:1],[5:2],[5:3], 
     [6:1],[6:2],[6:3], 
     [7:1],[7:2],[7:3] 
    ) 
) as pvt; 

könnte ein ähnliches Ergebnis wie das, was Sie wollen?

0

Überprüfen Sie dies und sehen Sie, ob es Ihr Problem löst ... ziemlich sicher, ich kann das weiter vereinfachen, aber müssen wissen, was die Dekodierungen für type_id (5 und 6) sind. Wird es mehr type_id's geben?

Auch result_id = 1 = Erfolg und 2 = Fehler richtig?

Frage, was passiert, wenn das Backup an einem bestimmten Tag überhaupt nicht ausgeführt wird :)? Wie gehst du mit dieser Situation um, da es für diesen Tag keine Aufzeichnungen gibt? :)

/* Create table and populate with sample data. 
create table Backups (hostname varchar(10), type_id int , result_id int , received datetime) 

insert into Backups (hostname , type_id ,result_id , received) values 
('SBS2011',  5 ,  1  ,'2016-06-28'), 
('SBS2011',  5 ,  1  ,'2016-06-28'), 
('SBS2011',  5 ,  1  ,'2016-06-29'), 
('SBS2011',  5 ,  1  ,'2016-06-29'), 
('SBS2011',  5 ,  1  ,'2016-06-30'), 
('SBS2011',  6 ,  1  ,'2016-06-30'), 
('SBS2011',  5 ,  2  ,'2016-07-01'), 
('SBS2011',  6 ,  2  ,'2016-07-01'), 
('SBS2011',  6 ,  2  ,'2016-07-01'), 
('SBS2011',  5 ,  1  ,'2016-07-02'), 
('SBS2011',  6 ,  1  ,'2016-07-02'), 
('SBS2011',  5 ,  1  ,'2016-07-03'), 
('SBS2011',  6 ,  1  ,'2016-07-03'), 
('SBS2011',  5 ,  1  ,'2016-07-04'), 
('SBS2011',  6 ,  1  ,'2016-07-04') 

select * , DatePart(w, received) from dbo.Backups b 

*/ 

Die Abfrage:

SELECT -- S.*, F.* 
     S.[hostname], 
     S.[1] as [1:1], 
     F.[1] as [1:2], 
     S.[2] as [2:1], 
     F.[2] as [2:2], 
     S.[3] as [3:1], 
     F.[3] as [3:2], 
     S.[4] as [4:1], 
     F.[4] as [4:2], 
     S.[5] as [5:1], 
     F.[5] as [5:2], 
     S.[6] as [6:1], 
     F.[6] as [6:2], 
     S.[7] as [7:1], 
     F.[7] as [7:2] 

FROM 
(
    select * from 
    (
     select [hostname], [type_id], datepart(w, received) as workday , result_id as res_type from [backups] where result_id = 1 

    ) TEMP 
    pivot 
    (
     count([type_id]) 
     for workday in 
     ([1], [2], [3], [4], [5], [6], [7]) 
    ) as pvt 

) S 
LEFT OUTER JOIN 
(
    select * from 
    (
     select [hostname], [type_id], datepart(w, received) as workday , result_id as res_type from [backups] where result_id = 2 

    ) TEMP 
    pivot 
    (
     count([type_id]) 
     for workday in 
     ([1], [2], [3], [4], [5], [6], [7]) 
    ) as pvt 

) F ON S.res_type = F.res_type - 1 
WHERE F.hostname IS NOT NULL 
+0

Ja, type_id's 1 bis 4 sind auch abhängig vom Host vorhanden. Es gibt auch mehr als diese beiden result_id's, aber das sollte nicht zu schwer zu erweitern sein. Sicherungen, die nicht ausgeführt werden konnten, sind in der Tat eine andere Frage und eine andere Abfrage. Fürs Erste bleibe ich bei der Summe der verschiedenen type_id's. Wenn die Summe weniger als die anderen Tage ist, ist etwas schief gelaufen. – mokum

+0

Type_id's repräsentieren die Quellsoftware und den Sicherungstyp. Type_id = 1 entspricht zum Beispiel Acronis VMprotect, type_id = 2 entspricht Acronis VMprotect Dual Destination, type_id = 3 entspricht Symantec BackupExec, etc – mokum