SQL语句,用于根据最新日期选择最新版本数据的值

SQL语句,用于根据最新日期选择最新版本数据的值,sql,sql-server,sql-server-2005,ansi-sql,Sql,Sql Server,Sql Server 2005,Ansi Sql,我有一个简单的查询,我想知道它是否可以更优雅地编码。最终解决方案必须符合ansi标准 我需要根据日期和版本从表中获取最新值。一个样本可以更清楚地解释: declare @t table (id int, due_date smalldatetime, version int, value nvarchar(10)) insert into @t select 3, '1/1/2010', 1, 'value 1' insert into @t select 3, '1/1/2010', 2,

我有一个简单的查询,我想知道它是否可以更优雅地编码。最终解决方案必须符合ansi标准

我需要根据日期和版本从表中获取最新值。一个样本可以更清楚地解释:

declare @t table (id int, due_date smalldatetime, version int, value nvarchar(10))

insert into @t select 3, '1/1/2010', 1, 'value 1'
insert into @t select 3, '1/1/2010', 2, 'value 2'
insert into @t select 3, '3/1/2010', 1, 'value 3'
insert into @t select 3, '3/1/2010', 2, 'value 4'
insert into @t select 3, '3/1/2010', 3, 'value 5'
insert into @t select 3, '3/1/2010', 4, 'value 6'
insert into @t select 3, '4/1/2010', 1, 'value 7'
insert into @t select 3, '4/1/2010', 2, 'value 8'
insert into @t select 3, '4/1/2010', 3, 'value 9'


select value from @t t
    inner join (select due_date, version=max(version) 
                from @t where due_date = (select max(due_date) from @t) group by due_date) maxes
    on t.due_date=maxes.due_date and t.version=maxes.version
所以我希望输出是

value 9
它基于上述查询

我对这个解决方案并不特别满意-有没有更好的方法来实现这一点?

您可以使用:

  SELECT TOP 1 
         x.value
    FROM @t x
ORDER BY x.due_date DESC, x.version DESC
不过,TOP不是ANSI。另一种选择是使用ANSI分析/排名/窗口功能:

SELECT x.value
  FROM (SELECT t.value,
               ROW_NUMBER() OVER (ORDER BY t.due_date DESC, t.version DESC) AS rank
          FROM @t t) x
 WHERE x.rank = 1
但这需要一个支持该功能的数据库-MySQL不支持,PostgreSQL只在v8.4中启动

SELECT
    value
FROM
    @t T1
LEFT OUTER JOIN @t T2 ON
    T2.id = T1.id AND
    (
        (T2.due_date > T1.due_date) OR
        (T2.due_date = T1.due_date AND T2.version > T1.version)
    )
WHERE
    T2.id IS NULL
或者


这是难以置信的快(即反应)。我从来没有认真使用过排名函数-我想现在是我学习的时候了。。。谢谢你的回答。编辑:这是SQL Server2005@Sean在这个例子中,我建议使用Road之前的Road号,或者考虑Tom H的任何一个查询。我有工作的代码,这对我来说是有意义的。TOP(如您之前所述)不符合ansi…@Sean:因为行数越快,在执行外部查询之前,它必须遍历整个表以确定秩值的属性。数据传递越少,查询效率就越高。啊,我明白了。我不认为与最初的查询相比,这将是一个主要障碍。然而,在过去的几分钟里,我确实看到一个论坛帖子说ROW_NUMBER()不是ansi标准。这是正确的吗?
SELECT
    value
FROM
    @t T1
WHERE
    NOT EXISTS
    (
        SELECT
        FROM
            @t T2
        WHERE
            T2.id = T1.id AND
            (
                (T2.due_date > T1.due_date) OR
                (T2.due_date = T1.due_date AND T2.version > T1.version)
            )
    )