Trouver la ligne avec une valeur maximale de id dans MySQL
-
19-09-2019 - |
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é ...
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 lorsques1.price
a1.version
est à samaximaleminimum valeur, il y a pass2.price
a2.version
avecplusmoins valeur et donc le correspondants2.article
a2.articleId
valeur estNULL
.
(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