我正在尝试从包含外键,日期和其他字段的源表中检索最新的行集。一组样本数据可以是:
create table #tmp (primaryId int, foreignKeyId int, startDate datetime,
otherfield varchar(50))
insert into #tmp values (1, 1, '1 jan 2010', 'test 1')
insert into #tmp values (2, 1, '1 jan 2011', 'test 2')
insert into #tmp values (3, 2, '1 jan 2013', 'test 3')
insert into #tmp values (4, 2, '1 jan 2012', 'test 4')
我希望检索的数据形式是:
foreignKeyId maxStartDate otherfield
------------ ----------------------- -------------------------------------------
1 2011-01-01 00:00:00.000 test 2
2 2013-01-01 00:00:00.000 test 3
也就是说,每foreignKeyId
只显示一行显示最新的开始日期和相关的其他字段 - primaryId
无关紧要。
我设法提出:
select t.foreignKeyId, t.startDate, t.otherField from #tmp t
inner join (
select foreignKeyId, max(startDate) as maxStartDate
from #tmp
group by foreignKeyId
) s
on t.foreignKeyId = s.foreignKeyId and s.maxStartDate = t.startDate
但是(a)这使用内部查询,我怀疑这可能导致性能问题,(b)如果原始表中的两行具有相同的foreignKeyId
和startDate
,它会提供重复的行
是否有一个查询只返回每个外键和开始日期的第一个匹配项?
答案 0 :(得分:2)
根据您的sql server版本,请尝试以下操作:
select *
from (
select *, rnum = ROW_NUMBER() over (
partition by #tmp.foreignKeyId
order by #tmp.startDate desc)
from #tmp
) t
where t.rnum = 1
答案 1 :(得分:1)
如果你想修复你的尝试而不是重新设计它,那么
select t.foreignKeyId, t.startDate, t.otherField from #tmp t
inner join (
select foreignKeyId, max(startDate) as maxStartDate, max(PrimaryId) as Latest
from #tmp
group by foreignKeyId
) s
on t.primaryId = s.latest
假设PrimaryID随着时间的推移而增加,那么就完成了这项工作。
关于内部查询的问题也可以在假设某些索引的情况下休息。