Domanda

Date un'occhiata alla tabella di MySQL seguito chiamati "articoli":

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

Nel tentativo di trovare una query per restituire Articles.id dove Articles.version è il numero massimo.

La tabella articoli attuale contiene oltre 10.000 voci.

Quindi in questo esempio voglio solo Articles.id 4 e 6 deve essere restituito. Ive stato a guardare parola chiave distinta e la funzione max (), ma non posso sembrano inchiodarlo.

Qualche suggerimento apprezzati ...

È stato utile?

Soluzione

Hai bisogno di una domanda secondaria qui:

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

Altri suggerimenti

MySQL manuale , questo fa il trucco:

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;

Dal manuale collegato:

  

Il LEFT JOIN lavora sulla base del fatto che, quando s1.price a1.version è al suo massima minima di valore, non v'è nessuna s2.price a2.version con maggiore meno valore e quindi il corrispondente s2.article a2.articleId è il valore NULL.

(ho modificato per rendere il loro testo corrispondono alla vostra situazione.)

È possibile utilizzare un subquery qui:

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

Dato che questo non è un subquery correlata, sarà piuttosto veloce (più veloce o più veloce di un join), quindi non c'è bisogno di preoccuparsi di questo. Ma tornerà tutti i valori che hanno il articleid max.

Naturalmente, vi consiglio che si lancia un indice su articleid (id supponendo che è già cluster). Che aiutarlo a tornare ancora più veloce.

Come notato nei commenti, se si desidera ottenere la versione massima per ogni articleid, è possibile effettuare le seguenti operazioni:

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

Questo creerà un join da quella subquery e tipicamente essere molto più veloce di una subquery correlata che seleziona il massimo per ogni articleid.

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

Forse qualcosa di simile:

select * from articoli in cui articleId in (select max (articleversion) da articoli)

Si può fare

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

Non so MySQL si esibirà con esso, ma Oracle e SQL server stanno bene con esso.

Tutte le risposte di cui sopra possono risolvere il problema dichiarato DJDonaL3000 s'. Ma, la maggior parte sono sub query correlate che ostacolano le prestazioni dell'applicazione. Se si utilizza un'applicazione cloud, allora, vi suggerisco di non utilizzare le query di cui sopra. Il modo migliore è quindi di mantenere due tabelle, A e B. A che contengono sempre l'ultima versione di questo articolo e B con i dettagli di tutte le versioni. Il problema è che ci saranno più aggiornamenti e inserimenti nelle tabelle, ma il recupero sarà più veloce, come avete solo bisogno di eseguire una normale query di selezione nella tabella A. In questo gruppo da e max in una query interna vi costerà

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top