SQL Server 2012. Ich muss eine Abfrage erstellen, um festzustellen, welche Jobs in welchem Status zu einem bestimmten Datum in der Vergangenheit waren (BONUS: wie lange sie in diesem Status waren.)SQL Konvertieren von Zeilen in Spalten zum Verfolgen des Jobstatus
ich habe eine Log-Tabelle Jobstatus mit den folgenden Spalten und Struktur:
JobStatusNo JobNo Status Rem Entered EnteredBy
-------------------------------------------------------------------------
1644897 420969 801 Reschedule 2017-09-20 17:58:18.503 1488
1644896 420969 812 Cancelled 2017-09-15 08:20:48.390 1267
1644895 420969 803 Confirmed 2017-09-14 10:13:25.733 1231
1644894 420969 802 Call Bob 2017-09-14 09:35:57.337 1231
1644893 420969 801 2017-09-08 18:18:16.490 1488
1644892 420965 807 2017-09-20 17:55:02.660 1488
1644891 420965 809 2017-09-20 17:47:52.340 1488
1644890 420965 806 2017-09-20 17:40:22.580 1488
1644889 420965 803 Confirmed 2017-09-20 17:05:30.870 1193
1644888 420965 801 2017-09-20 17:05:29.130 1193
1644877 420964 801 2017-09-20 17:02:16.830 1193
ich glaube, ich möchte eine bestimmte Auftragsnummer von jedem Status, war es in gefolgt haben, und wenn (plus I don sich nicht um Anmerkungen kümmern oder wer den Job eingegeben hat):
JobNo 1Status 1Entered 2Status 2Entered
--------------------------------------------------------------
420969 801 2017-09-20 17:58:18.503 812 2017-09-15.337
420968 801 2017-09-20 17:55:02.660
420967 801 2017-09-20 17:47:52.340
420966 801 2017-09-20 17:40:22.580
420965 803 2017-09-20 17:05:30.870
420965 801 2017-09-20 17:05:29.130
420964 801 2017-09-20 17:02:16.830
... mit mehreren Spalten nach Angabe von 3Status und 3Entered usw. Ich muss nur für 8 Status/eingegebene Daten codieren, da dies die größte Anzahl von Malen ist, die ein Auftrag im Status neu geordnet oder ersetzt wird. Wenn es schließlich mehr Spalten gibt, kann ich jede Antwort, die ich hier bekomme, auf diese Logik erweitern.
... weil meine eventuelle "Antwort" am 1. Juli 2016 (irgendein gegebenes Datum) sein wird: 87 Jobs waren in 801 Status, 255 Jobs waren in 806 Status und 5 Jobs waren in 809 Status. Tatsächlich muss ich Mathe machen, um zu bestimmen, WIE LANGE JEDER ARBEITSPLATZ AM BESONDEREN STATUS WAR, aber da dies meine erste Frage ist und ich nicht weiß, wie kompliziert meine Antwort sein wird, rufe ich sie hier an, wie ich ' Ich denke, ich kann den Rest herausfinden, sobald ich diese Status und Daten mit DateDiff säulenartig erhalten habe.
Ich habe jede Kombination aus UNPIVOT, Lag/Lead, Gruppierung, MAX und so weiter ausprobiert und kann nirgends hinkommen.
An diesem Punkt vermisse ich vielleicht sogar etwas Einfaches und fühle mich ziemlich dumm bei der Antwort, aber ich bin wirklich und fest stecken. Werde ich sogar den richtigen Weg gehen und versuchen, diese Spalten aus den Reihen herauszuholen, in denen sie sich gerade befinden? Gibt es eine Möglichkeit, das angegebene Datum zu verwenden und die Tabelle so zu verwenden, wie sie ist? Wenn etwas nicht klar ist, werde ich versuchen, in Updates oder Antworten zu klären. Prost!
Und hier ist die Antwort, die ich von @Fercstar wählte:
WITH A
AS
(
SELECT
*
,ROW_NUMBER() OVER(PARTITION BY JobNo ORDER BY Entered DESC) as StatusOrder
FROM MyJobStatusTable
)
SELECT
A.JobNo
,A.Status as Status1
,A.Entered as Entered1
,A2.Status as Status2
,A2.Entered as Entered2
,A3.Status as Status3
,A3.Entered as Entered3
,A4.Status as Status4
,A4.Entered as Entered4
,A5.Status as Status5
,A5.Entered as Entered5
,A6.Status as Status6
,A6.Entered as Entered6
,A7.Status as Status7
,A7.Entered as Entered7
,A8.Status as Status8
,A8.Entered as Entered8
,A9.Status as Status9
,A9.Entered as Entered9
FROM A
LEFT JOIN A as A2
ON A2.JobNo = A.JobNo
AND A2.StatusOrder = 2
LEFT JOIN A as A3
ON A3.JobNo = A.JobNo
AND A3.StatusOrder = 3
LEFT JOIN A as A4
ON A4.JobNo = A.JobNo
AND A4.StatusOrder = 4
LEFT JOIN A as A5
ON A5.JobNo = A.JobNo
AND A5.StatusOrder = 5
LEFT JOIN A as A6
ON A6.JobNo = A.JobNo
AND A6.StatusOrder = 6
LEFT JOIN A as A7
ON A7.JobNo = A.JobNo
AND A7.StatusOrder = 7
LEFT JOIN A as A8
ON A8.JobNo = A.JobNo
AND A8.StatusOrder = 8
LEFT JOIN A as A9
ON A9.JobNo = A.JobNo
AND A9.StatusOrder = 9
WHERE A.StatusOrder = 1
Läuft in 12 Sekunden gegen über einer Million Datenzeilen ohne temporäre Tabelle Management erforderlich. ELEGANT! Danke @Fercstar.
Danke John Cappelletti für die Neuformatierung! Viel besser lesbar. – DataVis4Fun