1

我正在尝试从包含外键、日期和其他字段的源表中检索最新的一组行。一组样本数据可以是:

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

是否有一个查询将只返回每个外键和开始日期的第一个匹配项?

4

2 回答 2

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
于 2013-09-24T21:33:50.097 回答
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 随着时间的推移而增加,就会完成这项工作。

假设一些索引,关于内部查询的疑虑也将被搁置。

于 2013-09-24T21:52:19.850 回答