Question

Jetez un oeil à la table MySQL ci-dessous appelés "articles":

+----+-----------+---------+------------------------+--------------------------+
| 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 essayant de trouver une requête pour retourner Articles.id où Articles.version est le nombre maximum.

Le tableau réel des articles contient plus de 10 000 entrées.

Donc, dans cet exemple, je veux seulement Articles.id 4 et 6 à renvoyer. Ive été regarder distincte et fonction mot-clé max () mais cant semblent clouer.

Toutes les suggestions ont apprécié ...

Était-ce utile?

La solution

Vous avez besoin d'une sous requête ici:

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

Autres conseils

De MySQL manuel , cela fait l'affaire:

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;

Dans le manuel lié:

  

Le LEFT JOIN fonctionne sur la base que lorsque s1.price a1.version est à sa maximale minimum valeur, il y a pas s2.price a2.version avec plus moins valeur et donc le correspondant s2.article a2.articleId valeur est NULL.

(j'edited pour rendre leur texte correspondent à votre situation.)

Vous pouvez utiliser ici une sous-requête:

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

Puisque ce n'est pas qu'une corrélation, il sera assez rapide (aussi vite ou plus vite que une jointure), de sorte que vous ne devez pas vous inquiéter à ce sujet. Mais ça va revenir toutes les valeurs qui ont le maximum articleid.

Bien sûr, je vous recommande de jeter un index sur articleid (en supposant id est déjà en cluster). Cela l'aidera à revenir encore plus vite.

Comme il est indiqué dans les commentaires, si vous voulez obtenir la version max pour chaque articleid, vous pouvez faire ce qui suit:

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

Cela va créer une jointure de cette sous-requête et généralement beaucoup plus rapide que qu'une corrélation qui sélectionne le maximum pour chaque articleid.

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

peut-être quelque chose comme:

select * from articles où articleid dans (select max (articleversion) d'articles)

Vous pouvez faire

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

Je ne sais pas MySQL interprétera avec elle, mais Oracle et SQL Server sont très bien avec elle.

Toutes les réponses ci-dessus peuvent résoudre le problème déclaré de DJDonaL3000. Mais, la plupart d'entre eux sont des requêtes sous corrélées qui font obstacle à la performance de l'application. Si vous utilisez une application cloud, je suggère de ne pas utiliser les requêtes ci-dessus. La meilleure façon est donc de maintenir deux tables A et B. A contenant toujours la dernière version de l'article et B ayant des détails sur toutes les versions. La question est, il y aura plus de mises à jour et insertions dans les tables, mais la récupération sera plus rapide que vous avez juste besoin d'exécuter une requête de sélection normale dans le tableau A. Faire groupe par et au maximum dans une requête intérieure vous coûtera

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top