You can use something like:
declare @date date = '2010-01-04' ;with ids as ( select distinct ind_id from myTable ) ,ranks as ( select * , ranking = row_number() over (partition by ind_id order by date desc) from myTable where date <= @date ) select ids.ind_id , ranks.value , ranks.date from ids left join ranks on ids.ind_id = ranks.ind_id and ranks.ranking = 1
SQL Fiddle with a demo .
Ideally, you will not use the DISTINCT operator to include ind_id values, but I used it in this case to get the results you need.
In addition, the standard clause for these types of requests; if you have duplicate data, you should consider the tie-break column in ORDER BY or use RANK instead of ROW_NUMBER .
Edited after updating OPs
Just add a new column to your existing query:
with ids as ( select distinct ind_id, name from myTable ) ,ranks as ( select * , ranking = row_number() over (partition by ind_id order by date desc) from myTable where date <= @date ) select ids.ind_id , ids.name , ranks.value , ranks.date from ids left join ranks on ids.ind_id = ranks.ind_id and ranks.ranking = 1
SQL Fiddle with a demo .
As in the previous one, it would be better to get the ind_id / name by attaching to the persistent data table, if available.
source share