2010-07-07 5 views
5

간단한 쿼리가 있으며 더 우아하게 코딩 될 수 있는지 궁금합니다. 최종 솔루션은 ANSI 호환이어야합니다.가장 최근의 날짜를 기준으로 최신 버전의 데이터 값을 선택하는 SQL 문

날짜와 버전을 기준으로 테이블에서 최신 값을 가져와야합니다. 샘플은 더 명확하게 설명 할 것 :

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 

될 것으로 기대한다.

나는이 솔루션에 만족하지 않습니다. 더 좋은 방법은 없습니까?

답변

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에서 시작하지 않습니다

+0

하하,이 그것도 내 마음을 교차하지 않았다 너무 간단하다 ... – cjk

+0

(응답, 즉). 나는 본격적으로 순위 기능을 사용한 적이 없다 - 나는 그것이 배웠던 절기라고 생각한다. 대답에 감사한다. 편집 : this is SQL Server 2005 – Sean

+0

@Sean :이 예제에서는 ROW_NUMBER 전에 TOP를 사용하거나 Tom H의 쿼리를 고려하는 것이 좋습니다. –

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) 
      ) 
    )