2017-07-24 1 views
1

J'ai une table. Je veux obtenir la dernière rangée pour chaque CoatingChambersID unique. Il y a 24 chambres uniques, et la dernière rangée indique combien de temps la chambre a été dans le dernier état.SQL: Obtenir la dernière ligne pour chaque ID unique

je peux obtenir une liste unique comme si:

SELECT distinct CoatingChambersID, MAX(LastDT) as LastDT 
    FROM [REO].[dbo].[CoatingChamberStateLogs] 
    group by CoatingChambersID 

Mais je ne peux pas comprendre comment rejoindre ce retour à la table d'origine.

Merci d'avance pour votre aide!

CoatingChamberStateLogsID CoatingChambersID StartDT LastDT IntervalMin CoatingChamberStatesID 
1001712 1003 2017-01-24 23:09:29.8 2017-01-25 03:04:32.6758500 235.053543986667 1007  
1001713 1006 2017-01-24 23:09:29.8 2017-01-25 00:30:30.8478433 81.0230772083333 1007  
1001714 1015 2017-01-24 23:09:29.8 2017-01-25 04:21:33.7601011 312.071614838333 1007  
1001715 1024 2017-01-24 23:09:29.8 2017-01-31 04:43:21.5643016 8973.86835151333 1001  
1001716 1016 2017-01-24 23:09:29.8 2017-01-25 00:01:30.4200122 52.01594669 1006  
1001717 1017 2017-01-24 23:09:29.8 2017-01-24 23:15:29.8261612 6.00604917333333 1006  
1001718 1018 2017-01-24 23:09:29.8 2017-01-26 01:42:49.4040548 1593.3323474 1006 0 
1001719 1019 2017-01-24 23:09:29.8 2017-01-25 02:25:32.3047026 196.047358196667 1005  
1001720 1020 2017-01-24 23:09:29.8 2017-01-24 23:12:29.8009482 3.00562895666667 1007  
1001721 1022 2017-01-24 23:09:29.8 2017-01-25 02:52:32.5995144 223.052271726667 1007  
1001722 1023 2017-01-24 23:09:29.8 2017-01-25 03:05:32.9236594 236.057674143333 1007  
1001723 1002 2017-01-24 23:09:29.4475820 2017-01-25 02:14:32.1723891 185.045413451667 1001  
1001724 1004 2017-01-24 23:09:29.8 2017-01-25 00:39:31.0878194 90.02707681 1001  
1001725 1005 2017-01-24 23:09:29.8 2017-01-24 23:18:29.8783565 9.006919095 1001  
+0

J'ai ajouté la balise SQL Server car le SQL ressemble à SQL Server. –

+0

Possible copie de [Récupérer le dernier enregistrement dans chaque groupe] (https://stackoverflow.com/questions/1313120/retrieving-the-last-record-in-each-group) –

Répondre

6

Utilisation row_number():

select ccs.* 
from (select ccs.*, 
      row_number() over (partition by ccs.CoatingChambersID order by ccs.LastDt desc) as seqnum 
     from [REO].[dbo].[CoatingChamberStateLogs] ccs 
    ) ccs 
where seqnum = 1; 

L'utilisation de select distinct avec group by est presque jamais correct.

Une autre façon amusante d'écrire la requête ne nécessite pas une sous-requête:

select top (1) with ties ccs.* 
from [REO].[dbo].[CoatingChamberStateLogs] ccs 
order by row_number() over (partition by ccs.CoatingChambersID order by ccs.LastDt desc); 
+0

Merde, vous êtes rapide! –

+0

Merci !!! J'ai besoin de RTFM sur le partitionnement. –

+0

Souhaitez-vous appliquer l'auto-joint être plus rapide? J'aime les 'avec des liens '.. ordre par tour pour éviter la sous-requête. – xQbert

0

Bien que j'aime la réponse de Gordon ... Je voulais offrir une alternative secondaire. Je n'ai pas pris le temps de déterminer si une application croisée serait plus efficace; mais compte tenu du coût de la participation ici, je pense que son peut-être plus efficace. mais sans test je ne peux pas dire.

SELECT B.* 
FROM [REO].[dbo].[CoatingChamberStateLogs] A 
CROSS APPLY (SELECT TOP 1 * 
      FROM [REO].[dbo].[CoatingChamberStateLogs] B 
      WHERE A.CoatingChambersID = B.CoatingChambersID 
      ORDER BY lastDT Desc) 

Je sais que cela fonctionne bien dans la plupart des dossiers de n haut dans les relations 1-M, mais comme cela est une auto se joindre à sa réponse peut donner lieu à un meilleur plan d'exécution, car il évite la jointure.