2017-07-12 5 views
0

Ich habe ein paar Abfragen und kombinieren ihre Ausgaben mit einer Union. Das kostet jedoch die CPU auf meinem Datenbankserver.Auswahl mehrerer überlappender Datumsbereiche als separate Spalten

Ich möchte die Gewerkschaften entfernen und sie alle in einer Anweisung kombinieren, wenn möglich.

Hier sind die Anfragen:

select [shift],p.wc, (sum(QtyMade)/sum(CREWHrs))/(max(t.UNITPERHRS)/NULLIF(max(t.CREW),0)) effy ,'YTD' datefield 
from Prod p left join #dtl_temp t on p.PN=t.PARTN 
where p.wc in ('999') and [date]>= DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()) - 1, 0) 
group by p.wc,[shift] 

union 

select [shift],p.wc, (sum(QtyMade)/sum(CREWHrs))/(max(t.UNITPERHRS)/NULLIF(max(t.CREW),0)) effy ,'Prior Year' datefield 
from Prod p left join #dtl_temp t on p.PN=t.PARTN 
where p.wc in ('999') and ([date]>= DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()) - 1, 0) and [date] < DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0)) 
group by p.wc,[shift] 

union 

select [shift],p.wc, (sum(QtyMade)/sum(CREWHrs))/(max(t.UNITPERHRS)/NULLIF(max(t.CREW),0)) effy ,'QTD' datefield 
from Prod p left join #dtl_temp t on p.PN=t.PARTN 
where p.wc in ('999') and ([date] >= '2017-07-01' and [date] < '2017-07-13') 
group by p.wc,[shift] 

union 

select [shift],p.wc, (sum(QtyMade)/sum(CREWHrs))/(max(t.UNITPERHRS)/NULLIF(max(t.CREW),0)) effy ,'MTD' datefield 
from Prod p left join #dtl_temp t on p.PN=t.PARTN 
where p.wc in ('999') and ([date] >= '2017-07-01' and [date] < '2017-07-13') 
group by p.wc,[shift] 

union 

select [shift],p.wc, (sum(QtyMade)/sum(CREWHrs))/(max(t.UNITPERHRS)/NULLIF(max(t.CREW),0)) effy ,'WTD' datefield 
from Prod p left join #dtl_temp t on p.PN=t.PARTN 
where p.wc in ('999') and ([date] >= '2017-07-10' and [date] < '2017-07-13') 
group by p.wc,[shift] 

union 

select [shift],p.wc, (sum(QtyMade)/sum(CREWHrs))/(max(t.UNITPERHRS)/NULLIF(max(t.CREW),0)) effy ,'Prior Quarter' datefield 
from Prod p left join #dtl_temp t on p.PN=t.PARTN 
where p.wc in ('999') and ([date] >= '2017-04-01' and [date] < '2017-07-01') 
group by p.wc,[shift] 

Der Ausgang davon ist:

shift wc effy    datefield 
1  999 0.951558640486598 YTD 
2  999 0.706728843730067 YTD 
3  999 0.831153497545209 YTD 
1  999 0.732836888916855 Prior Year 
2  999 0.548579728223933 Prior Year 
3  999 0.58957623455441 Prior Year 
1  999 0.617329386562882 QTD 
2  999 0.826112085298484 QTD 
3  999 1.0719875569761  QTD 
1  999 0.617329386562882 MTD 
2  999 0.826112085298484 MTD 
3  999 1.0719875569761  MTD 
1  999 0.617329386562882 WTD 
2  999 0.832089035926471 WTD 
3  999 1.0719875569761  WTD 
1  999 1.17254367493512 Prior Quarter 
2  999 0.939448907844456 Prior Quarter 
3  999 1.20640432761946 Prior Quarter 

Gibt es eine Möglichkeit für mich, all jene Daten zu kombinieren irgendwie eine CASE-Anweisung Bereiche in? Oder muss ich eine temporäre Tabelle mit den Datumskategorien (WTD, MTD, QTD usw.) mit Spalten für "von" und "bis" erstellen?

Ich bin mir nicht ganz sicher, wie ich dieses Ergebnis ohne die Gewerkschaften erreichen kann.

Die Daten, die Sie in den SELECTs sehen, stammen von einem Skript, das sie berechnet und die SQL-Abfrage erstellt.

+0

Warum müssen Sie dies gleichzeitig tun? für die Optimierung gibt es viele Aspekte zu prüfen, basierend auf dem anderen Namen von "datefiled", ich denke, das Ergebnis Rückgabe von jedem Teil der Abfrage ist einzigartig, könnten Sie versuchen, "union all" statt – LONG

+0

ich werde ändern Es geht um die Vereinigung, wie Sie und jemand anderes vorgeschlagen haben. Ich versuchte die Abfragen und die Ausführungszeit war ähnlich. Aber seit der Vereinigung ist alles weniger teuer, werde ich das verwenden. Die Ausgabe, die sie produzieren, wird in ein Diagramm geschoben. Ich denke, ich könnte jede Auswahl an den Server als eine separate Anfrage senden und sehen, ob das die Last erleichtern wird. – bobby

Antwort

0

Wenn ich richtig verstehe, erhalten Sie Ergebnisse von unten Abfrage: Ich denke, Sie suchen nach Gruppe durch Gruppieren von Sätzen oder Rollup oder Cube. Überprüfen Sie die für Ihre Anforderung

select [shift],p.wc, (sum(QtyMade)/sum(CREWHrs))/(max(t.UNITPERHRS)/NULLIF(max(t.CREW),0)) effy ,'Prior Year' datefield 
from Prod p left join #dtl_temp t on p.PN=t.PARTN 
where p.wc in ('999') 
group by grouping sets ([shift], p.wc,datepart(yyyy,[date]), datepart(qq, [date]), datepart(mm,[date])) 
0

Ja passt, können Sie separate Spalten für jeden Datumsbereich machen, und nur SUM Zeilen, die die Datumsbereich Kriterien erfüllen (ungetestet, Syntax möglicherweise nicht genau richtig sein) ...

SUM(CASE WHEN ([date] >= '2017-07-10' and [date] < '2017-07-13') THEN QtyMade ELSE 0 END) 

Bei neueren Versionen von SQL Server Sie auch IIF()

Eine Randnotiz verwenden könnte, ist UNION ALL weniger teuer dann UNION, weil es nicht doppelte Zeilen nicht beseitigt.