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.