Sélectionner l'logging le plus récent dans le sous-enfant

J'ai les tables / colonnes suivantes:

Parent: ParentID Child: ChildID ParentID SubChild: SubChildID ChildID Date 

Parent a 1 à plusieurs relation avec l' Child

Child a une relation de 1 à plusieurs avec SubChild

Pour chaque Parent , je dois get le SubChild avec la valeur Date la plus récente. Comment puis-je faire cela en utilisant SQL. J'ai essayé d'utiliser MAX(Date) , mais je n'arrive pas à comprendre comment joindre Parent et Child avec succès.

L'set de résultats idéal contiendrait toutes les SubChild jointes à toutes les colonnes SubChild du dernier logging.

Note: en utilisant MS SQL 2005+

Jetez un coup d'œil à ROW_NUMBER

Quelque chose comme

 ;WITH Vals AS ( SELECT p.ParentID, sc.SubChildID, ROW_NUMBER() OVER (PARTITION BY p.ParentID ORDER BY sc.[Date] DESC) RowID FROM Parent p INNER JOIN Child c ON p.ParentID = c.ParentID INNER JOIN SubChild sc ON c.ChildID = sc.ChildID ) SELECT ParentID, SubChildID FROM Vals WHERE RowID = 1 

Pour certaines dissortingbutions de données, cette approche pourrait être plus rapide.

 SELECT p.ParentID, sc.SubChildID, sc.Date FROM Parent p CROSS APPLY (SELECT TOP(1) s.SubChildID, s.Date FROM SubChild s JOIN Child c ON c.ChildID = s.ChildID WHERE c.ParentID=p.ParentID ORDER BY s.Date DESC) sc 

Vous pouvez le faire en utilisant une sous-requête corrélée, mais il est plus rapide d'utiliser les fonctions de classment SQL Server 2005. Tant que vous savez ce que vous faites, c'est.

Pour garder les choses simples, vous pouvez faire un sous-select. Dans mes tests, cela a la même performance que l'approche "cross-apply":

 select firstname, lastname, (Select top 1 Display from _notes where _notes.ParentId = c.Id order by createdon desc) as MostRecentNote from _contacts c 

Pour les loggings de 47k, cette approche de "sous-sélection" prend environ 4 secondes. Pour le rendre rapide, j'ai ajouté un index sortingé sur _Notes qui incluait ParentId, CreatedOn (Sorted descending) et la colonne Display était incluse). Cela réduit la requête à less de 1 seconde sur 47k loggings.