2009-08-20 7 views
5

Werfen Sie einen Blick auf der MySQL-Tabelle unter dem Namen „Artikel“:Suche mit maximalem Wert von id in MySQL Zeile

+----+-----------+---------+------------------------+--------------------------+ 
| id | articleId | version | title     | content     | 
+----+-----------+---------+------------------------+--------------------------+ 
| 1 |   1 | 0.0  | ArticleNo.1 title v0.0 | ArticleNo.1 content v0.0 | 
| 2 |   1 | 1.0  | ArticleNo.1 title v1.0 | ArticleNo.1 content v1.0 | 
| 3 |   1 | 1.5  | ArticleNo.1 title v1.5 | ArticleNo.1 content v1.5 | 
| 4 |   1 | 2.0  | ArticleNo.1 title v2.0 | ArticleNo.1 content v2.0 | 
| 5 |   2 | 1.0  | ArticleNo.2 title v1.0 | ArticleNo.2 content v1.0 | 
| 6 |   2 | 2.0  | ArticleNo.2 title v2.0 | ArticleNo.2 content v2.0 | 
+----+-----------+---------+------------------------+--------------------------+ 

Im Versuch mit einer Abfrage zu kommen Articles.id zurückzukehren, wo Articles.version ist die maximale Anzahl.

Die tatsächliche Artikel Tabelle enthält über 10.000 Einträge.

Also in diesem Beispiel möchte ich nur Artikel.id 4 und 6 zurückgegeben werden. Ich habe Keyword distinct und Funktion max() betrachtet, aber kann nicht scheinen es zu nageln.

Alle geschätzt Vorschläge ...

Antwort

4

Sie müssen eine Sub-Abfrage hier:

SELECT a.id, a.version 
FROM articles a 
WHERE a.version = (
    SELECT MAX(version) 
    FROM articles b 
    WHERE b.articleId = a.articleId 
) 
+0

Dies gibt nur die neuesten Versionen von Artikeln zurück und verwirft die vorherigen/älteren Versionen. Schöne Fragen Jungs, vielen Dank! –

+0

Nur für den Rekord: T.J. Crowder hat in seiner Antwort darauf hingewiesen, dass eine Unterabfrage nicht obligatorisch ist: Es kann auch mit einem LEFT JOIN gemacht werden. – soulmerge

4

Sie eine Unterabfrage hier verwenden können:

select 
    a.id 
from 
    articles a 
where 
    a.version = (select max(version) from articles) 

Da dies nicht eine korrelierte Unterabfrage ist, wird es ziemlich schnell sein (so schnell oder schneller als ein beitreten), also brauchst du dir darüber keine Sorgen zu machen. Aber es wird alle Werte zurückgeben, die das Maximum articleid haben.

Natürlich würde ich empfehlen, dass Sie einen Index auf articleid werfen (vorausgesetzt, id ist bereits geclustert). Das wird ihm helfen, noch schneller zurückzukehren.

Wie in den Kommentaren erwähnt, wenn Sie die max-Version für jede articleid erhalten möchten, können Sie folgendes tun:

select 
    a.id 
from 
    articles a 
    inner join (select articleid, max(version) 
       from articles group by articleid) as b on 
     a.articleid = b.articleid 
     and a.version = b.version 

Dies ist eine aus dieser Unterabfrage beitreten erstellen und in der Regel viel schneller als eine korrelierte Unterabfrage, die das Maximum für jede articleid auswählt.

+1

Das ist nicht richtig - das wählt die maximale Artikel-ID ist max, nicht Artikelversion. – tw39124

+0

@Tom: Ja, und jetzt habe ich es behoben, also ist es richtig. – Eric

+0

Beachten Sie, dass nur Artikel mit der gleichen Version ausgewählt werden. Wenn Sie die neueste Version von * jedem * Artikel abrufen möchten, werfen Sie einen Blick auf meine Antwort unten. – soulmerge

1

SELECT Articles.id FROM Articles WHERE Articles.version IN (SELECT MAX(Articles.version) FROM Articles)

1

vielleicht so etwas wie:

select * from Artikeln, in denen articleid in (select max (articleversion) aus Artikeln)

1

können Sie tun

SELECT articles.id 
    FROM articles a 
WHERE NOT EXISTS(SELECT * FROM articles a2 WHERE a2.version > a.version) 

I don‘ Ich weiß, dass MySQL damit arbeiten wird, aber Oracle und SQL Server sind in Ordnung.

5

Vom MySQL manual, tut dies der Trick:

SELECT a1.id 
FROM Articles a1 
LEFT JOIN Articles a2 ON a1.articleId = a2.articleId AND a1.version < a2.version 
WHERE a2.articleId IS NULL; 

den Link für Rationale See.

+0

Beachten Sie auch, dass Unterabfragen in der WHERE-Klausel in MySQL möglicherweise für jede Zeile im Ergebnis ausgeführt werden, daher ist dies wahrscheinlich die beste Antwort. –

1

Alle oben genannten Antworten lösen das angegebene Problem von DJDonaL3000. Die meisten von ihnen sind jedoch korrelierte Unterabfragen, die die Ausführung der Anwendung behindern. Wenn Sie eine Cloud-Anwendung verwenden, schlage ich vor, die obigen Abfragen nicht zu verwenden. Der beste Weg besteht dann darin, zwei Tabellen A und B zu pflegen. A enthält immer die neueste Version des Artikels und B enthält Details zu allen Versionen. Das Problem ist, dass es mehr Aktualisierungen und Einfügungen in die Tabellen geben wird, aber der Abruf wird schneller, da Sie nur eine normale Auswahlabfrage in Tabelle A ausführen müssen.Wenn Sie in einer inneren Abfrage eine Gruppierung nach max durchführen, kostet das