2012-01-13 10 views
0

是什麼(如果區分重要的Sybase SQL)爲此在SQL的最佳方式:需要選擇一個版本列匹配的最新版本,從表中的行

表:(帶一些樣本數據)

| id | value1 | value2 | version | 
================================== 
| 1 | A11 | B11 | 1  | 
| 1 | A12 | B12 | 2  | 
| 2 | A21 | B21 | 1  | 
| 3 | A32 | B32 | 2  | 

Unique key: (id, version). Index: (id, version) 

數據集大小:〜100K表中的行,具有典型的查詢的WHERE子句限制結果來10-100 ID和版本#分別是1,2或3,有時

我需要做什麼:每一個ID,檢索與最高版本的行爲ID

| id | value1 | value2 | version | 
================================== 
| 1 | A12 | B12 | 2  | <---- Chosen since 2>1 for id=1 
| 2 | A21 | B21 | 1  | 
| 3 | A32 | B32 | 2  | 

簡單的解決方案:我能想到的最顯而易見的方法是使用子查詢:

SELECT id, value1, value2 
FROM T 'T1' 
WHERE id in (1, 2, 3, ... 10) -- Obviously a fake sample clause 
AND version = (SELECT MAX(version) FROM T 'T2' 
        WHERE T1.id=T2.id 
        AND id in (1, 2, 3, ... 10) 
       ) 

問題:這是最好的方法嗎?

「最佳」在這裏是指:

  1. 「表現最好的平均」(給定的數據集的大小,典型的查詢的大小和上述顯示索引)。

  2. 對於具有類似性能的方法,最優雅的代碼方式。顯然,這在旁觀者的眼中,但是如果你能夠證明代碼更具可擴展性/可維護性,那麼這就清楚地表明瞭優雅的代碼。

回答

2
SELECT * 
FROM (
    SELECT id, 
      value1, 
      value2, 
      version, 
      max(version) over (partition by id) as max_version 
    FROM T 
    WHERE id IN (1, 2, 3, ... 10) 
) t2 
WHERE version = max_version 

根據您的DBMS(尤其是優化器)和索引,這可能比子選擇更快,因爲只需要對錶進行單次掃描。

+0

我喜歡那樣美觀,謝謝 – DVK 2012-01-13 21:29:03

0

我想用JOIN而不是子查詢使它更具可讀性:

SELECT id, value1, value2 
FROM T 'T1' 
INNER JOIN (
    SELECT id,MAX(version) as version 
    FROM T 
    WHERE id IN (...) 
    GROUP BY id) T2 
ON (T1.id = T2.id AND T1.version=T2.version) 
WHERE T1.id in (1, 2, 3, ... 10) 

相比原來的查詢應該不會造成任何性能開銷/效益。