2009-02-11 73 views
49

返回我有一個數據庫表是這樣的:MySQL的 - 控制該行由一組由

id version_id field1 field2 
1  1    texta  text1 
1  2    textb  text2 
2  1    textc  text3 
2  2    textd  text4 
2  3    texte  text5 

如果你沒有工作了,它包含了一些行的版本,然後一些文本數據。

我想查詢它並返回每個ID的編號最高的版本。 (所以第二行和最後一行只在上面)。

我已經嘗試使用group by by order by version_id DESC - 但它似乎是在它的分組後排序,所以這是行不通的。

任何人有任何想法?我無法相信這是無法完成的!

UPDATE:

想出這個,它的工作原理,但使用子查詢:

SELECT * 
FROM (SELECT * FROM table ORDER BY version_id DESC) t1 
GROUP BY t1.id 
+0

相關:http://stackoverflow.com/questions/13700456/mysql-group-by-implementation-details-which-row-mysql-chooses-in-a-group-by-qu – ripper234 2012-12-04 10:12:14

回答

44

這就是所謂的選擇組間最大的列。 Here are several different approaches for mysql.

這是我會怎麼做:

SELECT * 
FROM (SELECT id, max(version_id) as version_id FROM table GROUP BY id) t1 
INNER JOIN table t2 on t2.id=t1.id and t1.version_id=t2.version_id 

這將是比較有效的,但MySQL將在內存中的子查詢創建臨時表。我假設你已經有了這個表的索引(id,version_id)。

這是SQL中的一個缺陷,您或多或少不得不針對此類問題使用子查詢(semi-joins是另一個示例)。

子查詢在mysql中沒有得到很好的優化,但是不相關的子查詢並沒有那麼糟糕,只要它們不是很大以至於它們會被寫入磁盤而不是內存。鑑於在這個查詢中只有兩個整數,子查詢可能在發生之前就有數百萬行,但第一個查詢中的select *子查詢可能很快就會遭受這個問題的困擾。

+3

鏈接的文章是非常太好了! – onnodb 2009-02-11 15:39:14

+0

Ta爲鏈接,並舉例說明。我們結束了與子查詢選項。 – benlumley 2009-02-11 22:26:25

+0

對於鏈接的文章。謝謝。 – dotancohen 2014-01-19 13:54:28

3

我認爲這樣做,不知道它是最好的還是最快的。

SELECT * FROM table 
WHERE (id, version_id) IN 
    (SELECT id, MAX(version_id) FROM table GROUP BY id) 
0

這是僞代碼,但這樣的事情應該只是罰款

select * 
from table 
inner join 
(
    select id , max(version_id) maxVersion 
    from table 
) dvtbl ON id = dvtbl.id && versionid = dvtbl.maxVersion 
0

我通常這樣做有一個子查詢:

選擇ID,VERSION_ID,FIELD1,FIELD2從數據表爲DT其中id =(從datatable選擇ID,其中id = dt.id order by version_id desc limit 1)

-1

我認爲這是你想要的。

select id, max(v_id), field1, field2 from table group by id 

結果我從那些

1,2,TEXTB,文本2

2,3,texte,text5

編輯: 我重新創建表並使用id插入相同的數據,其中version_id是複合主鍵。這給了我前面提供的答案。它也在MySQL中。

2
SELECT id, version_id, field1, field2 
FROM (
    SELECT @prev = id AS st, (@prev := id), m.* 
    FROM (
      (SELECT @prev := NULL) p, 
      (
      SELECT * 
      FROM mytable 
      ORDER BY 
        id DESC, version_id DESC 
      ) m 
    ) m2 
WHERE NOT IFNULL(st, FALSE); 

沒有子查詢,一個通上UNIQUE INDEX ON MYTABLE (id, version_id)如果你有一個(我想你應該)

-2

沒有測試,但這樣的事情可能工作:

SELECT * FROM表GROUP BY ID ORDER BY MAX(VERSION_ID)DESC

0

這個查詢可以通過做任務時不帶組:

SELECT * FROM table AS t 
LEFT JOIN table AS t2 
    ON t.id=t2.id 
    AND t.version_id < t2.version_id 
WHERE t2.id IS NULL 

它不需要任何臨時表。