Frage

Schauen Sie sich die folgende MySQL -Tabelle mit dem Namen "Artikel" an:

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

Ich versuche, eine Abfrage zu finden, um Artikel zurückzugeben.

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

In diesem Beispiel möchte ich nur Artikel. ID 4 und 6 werden zurückgegeben. Ich habe mir das Keyword -Different und die Funktion max () angesehen, kann es aber nicht nageln.

Alle Vorschläge geschätzt ...

War es hilfreich?

Lösung

Sie brauchen hier eine Unterabfrage:

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

Andere Tipps

Von dem Mysql Handbuch, Dies macht den 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;

Aus dem verknüpften Handbuch:

Das LEFT JOIN funktioniert auf der Grundlage, dass wann s1.price a1.version ist bei seinem maximal Minimum Wert, es gibt keine s2.price a2.version mit einer größer kleiner Wert und damit der entsprechende s2.article a2.articleId Wert ist NULL.

(Ich habe bearbeitet, um ihren Text mit Ihrer Situation übereinzustimmen.)

Sie können hier eine Unterabfrage verwenden:

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

Da dies keine korrelierte Unterabfrage ist, wird es ziemlich schnell sein (so schnell oder schneller als ein Join), sodass Sie sich darüber keine Sorgen machen müssen. Aber es wird alle Werte zurückgeben, die das max haben articleid.

Natürlich würde ich empfehlen, dass Sie einen Index aufwerfen articleid (Annahme id ist bereits gruppiert). Das wird es noch schneller zurückkehren.

Wie in den Kommentaren erwähnt, wenn Sie die maximale Version für jeden erhalten möchten articleid, Sie können 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 erzeugt einen Join aus dieser Unterabfrage und ist in der Regel viel schneller als eine korrelierte Unterabfrage, die das max für jeden auswählt articleid.

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

Vielleicht so etwas wie:

Wählen Sie * aus Artikeln, in denen ArtikelID in (Select Max (Artikelversion) aus Artikeln ausgewählt werden).

Du kannst tun

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

Ich weiß nicht, dass MySQL damit auftreten wird, aber Oracle und SQL Server sind damit einverstanden.

Alle oben genannten Antworten können das angegebene Problem von Djdonal3000 lösen. Die meisten von ihnen sind jedoch korrelierte Unterabfragen, die die Leistung der Anwendung behindern. Wenn Sie eine Cloud -Anwendung verwenden, schlage ich vor, die oben genannten Abfragen nicht zu verwenden. Der beste Weg ist es, zwei Tabellen zu verwalten, A und B. A, die immer die neueste Version des Artikels und B enthält, die Details aller Versionen haben. Das Problem besteht darin

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top