Reputation: 40202
I have the following tables/columns:
Parent:
ParentID
Child:
ChildID
ParentID
SubChild:
SubChildID
ChildID
Date
Parent
has 1 to Many relationship with Child
Child
has 1 to Many relationship with SubChild
For every Parent
, I need to get the SubChild
with the most recent Date
value.
How can I do this using SQL. I've tried using MAX(Date)
,
but I can't seem to figure out how to join Parent
and Child
successfully.
The ideal result set would contain all the Parent
s joined with all the SubChild
columns of the latest record.
Note: using MS SQL 2005+
Upvotes: 4
Views: 2607
Reputation: 5914
To keep things simple, you can do a sub-select. In my testing this has the same performance as the "cross-apply" approach:
select firstname, lastname,
(Select top 1 Display from _notes where _notes.ParentId = c.Id order by createdon desc) as MostRecentNote
from _contacts c
For 47k records, this "sub-select" approach takes about 4 seconds. To make it fast, I added a sorted index on _Notes that included ParentId, CreatedOn (Sorted descending) and the Display column was included). This drops the query to less than 1 second on 47k records.
Upvotes: 0
Reputation: 453707
For some data distributions this approach could be faster.
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
Upvotes: 2
Reputation: 166486
Have a look at using ROW_NUMBER
Something like
;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
Upvotes: 4
Reputation: 27214
You can do this using a correlated subquery, but it is faster to use the SQL Server 2005 ranking functions. As long as you know what you're doing, that is.
Upvotes: 0