SQL Server 2012. J'ai besoin de créer une requête pour déterminer quels travaux étaient dans quel état à une date donnée dans le passé (BONUS: durée de leur statut.)SQL Convertir les lignes en colonnes pour suivre l'état du travail
J'ai une table de journal d'état du job avec les colonnes suivantes et structure:
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
Je pense que je voudrais avoir un certain nombre d'emplois en particulier suivi par chaque état il était, et quand (de plus, je don ne vous souciez pas des remarques ou qui est entré dans le travail):
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
... avec plus de colonnes après avoir indiqué 3Status et 3Enter, etc. J'ai seulement besoin de coder pour 8 statuts/dates saisies car c'est le nombre le plus élevé de fois qu'un travail est réorganisé ou remplacé dans l'état. S'il y a finalement plus de colonnes, je serai en mesure d'étendre toute réponse que je reçois ici pour inclure cette logique.
... parce que ma "réponse" éventuelle sera le 1er juillet 2016 (n'importe quelle date donnée): 87 postes étaient en 801 postes, 255 en 806 postes et 5 en 809 postes. En fait, j'ai besoin de faire des calculs pour déterminer à quel moment chaque emploi était dans un état particulier, mais comme c'est ma première question et je ne sais pas comment ma réponse sera compliquée, je l'appelle ici comme je l'ai fait. Je devine que je peux comprendre le reste une fois que je reçois ces statuts et dates columnar avec DateDiff.
J'ai essayé toutes les combinaisons que je peux penser de UNPIVOT, Lag/Lead, groupant, MAX, et cetera et ne peut obtenir nulle part.
À ce stade, il m'est même peut-être manquant quelque chose de simple et je me sentirai très bête à la réponse, mais je suis bel et bien coincé. Est-ce que je vais même dans le bon sens en essayant de faire sortir ces colonnes des rangées où elles se trouvent actuellement? Y a-t-il un moyen de prendre la date donnée et d'utiliser la table telle quelle? Si quelque chose n'est pas clair, je vais essayer de clarifier dans les mises à jour ou les réponses. À votre santé!
Et voici la réponse que j'ai choisi de @Fercstar:
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
Se exécute en 12 secondes contre plus d'un million de lignes de données sans gestion de la table temporaire nécessaire. ÉLÉGANT! Merci @Fercstar.
Merci John Cappelletti pour le reformater! Beaucoup plus lisible. – DataVis4Fun