2010-09-07 27 views
4

T-SQL查詢:根據下表上獲取最新的行接近

Table_A 

ID Rev Description 
----------------------------------- 
1 1 Some text. 
1 2 Some text. Adding more. 
1 3 Some text. Ading more & more. 

以上將不斷增加新的一行時,用戶更新的說明。

我想用MAX(Rev)[即最新描述]。

爲了得到這個我做了以下內容:

;with AllDescriptions As 
(
select 
     ID 
     , Rev 
     , Description 
     , ROW_NUMBER() over (partition by ID order by Rev desc) as RowNum 
     from Table_A 
     Where ID = 1 
) 
select ID, Rev, Description from AllDescription 
where RowNum = 1 

最近,我看到了一個不同的方法來獲得相同的結果

select b.* from 
(
select ID, MAX(Rev) as MaxRev 
from Table_A 
where ID = 1 
group by ID 
) as a 
inner join 
(
select ID, Rev, Description from Table_A where ID = 1 
) as b 
on a.ID = b.ID and a.MaxRev = b.Rev 

從學習的角度來看,我想知道上述兩個哪方法更好?或者如果還有更好的方法來做同樣的事情?

+0

檢查執行計劃。第2版​​可能會展示一些單尋求加分區優化器的魔力。我以前見過這個例子,不記得在哪裏。 * SQL Server 2008內部:T-SQL編程*,也許? – 2010-09-07 23:41:10

+0

@Peter - 我似乎還記得,他們在這些書中忘記了細節,對'JOIN'或'TOP 1'進行了比較。 – 2010-09-07 23:45:15

+0

我剛剛試過兩種方法 - '統計信息IO'爲這兩個選項提供了幾乎相同的讀取次數,並在表上支持聚簇索引。查詢計劃認爲ROW_NUMBER變體的價格要高得多。 '查詢相對於批量的成本' - 但我認爲在這種情況下這是誤導性的。 – 2010-09-07 23:55:37

回答

1

在引入Row_Number()之前,第二種方法看起來像SQL Server 2000方法。這是Greatest-n-per-group problem

評價他們,你應該看看執行計劃和I/O統計運行SET STATISTICS IO ON

當然,你已經給出了具體的例子下面來完成工作

select TOP 1 
     ID 
     , Rev 
     , Description 
     from Table_A 
     Where ID = 1 
ORDER BY Rev desc 
0

我傾向於贊成第一種方法 - 從可讀性的角度來看,一旦您對ROW_NUMBER()OVER ...語法感到滿意,那麼它就會更具可讀性。從性能角度來看,如果兩者之間有很大差異,我會感到驚訝 - 如果有的話,我會期望第二個會變得更糟 - 但我的立場是要糾正的!

1

如果你有一個父表,每個ID只列出一次,這有時會超過其他策略,包括row_number解決方案:

SELECT 
    X.* 
FROM 
    ParentTable P 
    CROSS APPLY (
     SELECT TOP 1 * 
     FROM Table_A A 
     WHERE P.ID = A.ID 
     ORDER BY A.Rev DESC 
    ) X 

狂,專利(開個玩笑),單次掃描魔查詢,而這往往優於其他方法還有:

SELECT 
    ID, 
    Rev = Convert(int, Substring(Packed, 1, 4)), 
    Description = Convert(varchar(100), Substring(Packed, 5, 100)) 
FROM 
    (
     SELECT 
     ID, 
     Packed = Max(Convert(binary(4), Rev) + Convert(varbinary(100), Description)) 
     FROM Table_A 
     GROUP BY ID 
    ) X 

注意:不建議使用此最後一個方法,但它的樂趣,模擬第一/最後聚集在MS Access中。