Skip to content
Advertisement

SQL subquery with latest record

I’ve read just about every question on here that I can find that is referencing getting the latest record from a subquery, but I just can’t work out how to make it work in my situation.

I’m creating an SSRS report for use on SQL Server 2008.

In the database is a table of contacts and DBSdata. I want to pull up a list of contacts and the latest record (many of the fields from that row) from the DBSdata table (expiry date furthest in the future)

And the result I’d like is:

[The DBSData table doesn’t have it’s own Primary Key field – that’s not something I have control over, unfortunately… And the ordinal increases per contact, so FKContactID+Ordinal is unique….]

This is the code I’ve kind of got to, but it isn’t working. The system I’m uploading the SSRS to doesn’t give me any useful error message at all, so I can’t be more specific about what isn’t working I’m afraid. I get none of the SSRS report displayed, just an error saying the dataset source isn’t working.

I suspect it’s something to do with that WHERE in the subquery, but if I don’t have that, that whole table is using the WHOLE table and returning 1 row, not the top 1 for that contact.

Advertisement

Answer

Your method would work using APPLY, instead of JOIN:

Technically APPLY implements something called a lateral join. This is like a correlated subquery, but it can return multiple rows and multiple columns. Lateral joins are very powerful, and this is a good example for using them.

For performance, you want indexes on DBSData(FKContactID, ExpiryDate DESC) (perhaps including the other columns you want as well) and Contacts(ContactName).

With the right indexes, I would expect this to have performance at least as good as other methods.

An alternative that also typically has good performance is using a correlated subquery for filtering:

Note that to match the LEFT JOIN, the correlation condition needs to be in the ON clause, not the WHERE clause.

Finally, if you do use window functions, I would recommend a subquery for getting the first row:

Doing the subquery before the JOIN gives more opportunities for the optimizer to produce a better execution plan.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement