5

簡単なクエリがあり、もっとエレガントにコーディングできるかどうか疑問に思っています。最終的なソリューションは、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

これは上記のクエリに基づいています。

私はこのソリューションに特に満足していません-これを達成するためのより良い方法はありますか?

4

2 に答える 2

5

あなたが使用することができます:

  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でのみ開始されました...

于 2010-07-07T15:31:54.133 に答える
1
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

また...

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)
            )
    )
于 2010-07-07T15:32:10.670 に答える