Reputation: 29
I have a subquery (MS SQL 2016) to pull the most recent measurement value for a specific measure. I need to link the resulted measure value back to my main query by PAT_ID. The problem I'm running into is that I can't get the MAX Date (most recent date) to pull only one record in the subquery.
The following query returns numerous records and not the most recent record only
SELECT distinct meas.MEAS_VALUE, rec.pat_id, MAX(meas.ENTRY_TIME) "MAX ET"
from ip_flwsht_rec rec
inner join [CLARITY].[dbo].[IP_FLWSHT_MEAS] meas on rec.fsd_id=meas.FSD_ID
and meas.flo_meas_id='14'
and meas.MEAS_VALUE is not null
where meas.ENTRY_TIME>=(DATEADD(day, DATEDIFF(day, 0,getdate()) - 548, 0))
AND rec.pat_id = 'CENSORED'
GROUP BY meas.MEAS_VALUE, rec.PAT_ID
This returns the results...
This same patient has 9 results but I only want the most recent. Not sure what I'm doing wrong and any assistance is greatly appreciated.
Upvotes: 0
Views: 225
Reputation: 20794
Depending on your requirements, the top 1
approach in @Zack's answer might be the best approach. It features one of the most redeeming of all qualities, simplicity.
If the top 1
approach does not satisfy your requirements, then you are pretty close. In your question, you say, I need to link the resulted measure value back to my main query by PAT_ID
. Actually, you need to link it with two fields, the pat_id, and the entry_time.
To ensure you only get one record per patient, change this:
SELECT distinct meas.MEAS_VALUE, rec.pat_id, MAX(meas.ENTRY_TIME) "MAX ET"
to this:
SELECT rec.pat_id, MAX(meas.ENTRY_TIME) "MAX ET"
Your final query then resembles this:
with mostRecentRecords as (
select rec.pat_id, MAX(meas.ENTRY_TIME) mostRecentEntry
from etc
group by rec.pat_id
)
select whatever
from your tables
join mostRecentRecords on rec.pat_id = mostRecentRecords.pat_id
and meas.entry_time = mostRecentEntry
Upvotes: 2
Reputation: 1503
Just add TOP(1) in your select, and sort it by time:
SELECT distinct TOP(1) meas.MEAS_VALUE, ...
...
ORDER BY meas.ENTRY_TIME DESC
Upvotes: 1
Reputation: 38023
Using row_number()
to order the meas
records prior to joining, and partitioned by fsd_id
. Resulting in the latest record from meas
for each fds_id
without the need for group by
or aggregation.
select
meas.MEAS_VALUE
, rec.pat_id
, [Max ET] = meas.ENTRY_TIME
from ip_flwsht_rec rec
inner join (
select *
, rn = row_number() over (partition by fsd_id order by ENTRY_TIME desc)
from [CLARITY].[dbo].[IP_FLWSHT_MEAS]
) as meas
on rec.fsd_id=meas.FSD_ID
and meas.rn = 1 /* just the latest row based on `entry_time` */
and meas.flo_meas_id='14'
and meas.MEAS_VALUE is not null
where meas.ENTRY_TIME>=(dateadd(day, datediff(day, 0,getdate()) - 548, 0))
and rec.pat_id = 'CENSORED'
Upvotes: 0