A première vue...
Tout ce dont vous avez besoin est un GROUP BY
avec la clause MAX
fonction d'agrégation :
SELECT id, MAX(rev)
FROM YourTable
GROUP BY id
Ce n'est jamais aussi simple, n'est-ce pas ?
Je viens de remarquer que vous avez besoin du content
également.
Il s'agit d'une question très courante en SQL : trouver l'ensemble des données pour la ligne avec une certaine valeur maximale dans une colonne par un certain identifiant de groupe. J'ai souvent entendu cette question au cours de ma carrière. En fait, c'était l'une des questions auxquelles j'ai répondu lors de l'entretien technique de mon emploi actuel.
En fait, c'est tellement courant que la communauté StackOverflow a créé un tag unique pour traiter ce genre de questions : le plus grand-n par-groupe .
En fait, vous avez deux approches pour résoudre ce problème :
Joindre avec simple group-identifier, max-value-in-group
Sous-requête
Dans cette approche, vous trouvez d'abord le group-identifier, max-value-in-group
(déjà résolu ci-dessus) dans une sous-requête. Ensuite, vous joignez votre table à la sous-requête avec une égalité sur les deux. group-identifier
et max-value-in-group
:
SELECT a.id, a.rev, a.contents
FROM YourTable a
INNER JOIN (
SELECT id, MAX(rev) rev
FROM YourTable
GROUP BY id
) b ON a.id = b.id AND a.rev = b.rev
Jointure à gauche avec self, modification des conditions de jointure et des filtres
Dans cette approche, vous avez laissé la table se joindre à elle-même. L'égalité va dans le group-identifier
. Alors, 2 mouvements intelligents :
- La deuxième condition de jonction est que la valeur du côté gauche soit inférieure à la valeur du côté droit.
- Lorsque vous effectuez l'étape 1, la ou les lignes qui ont effectivement la valeur maximum auront
NULL
dans la partie droite (c'est un LEFT JOIN
vous vous souvenez ?). Ensuite, nous filtrons le résultat joint, en montrant seulement les lignes où le côté droit est NULL
.
Donc vous vous retrouvez avec :
SELECT a.*
FROM YourTable a
LEFT OUTER JOIN YourTable b
ON a.id = b.id AND a.rev < b.rev
WHERE b.id IS NULL;
Conclusion
Les deux approches aboutissent exactement au même résultat.
Si vous avez deux lignes avec max-value-in-group
pour group-identifier
les deux lignes seront dans le résultat dans les deux approches.
Les deux approches sont compatibles avec SQL ANSI et fonctionneront donc avec votre SGBDR préféré, quelle que soit sa "saveur".
Les deux approches sont également favorables à la performance, mais les résultats peuvent varier (SGBDR, structure de la base de données, index, etc.). Ainsi, lorsque vous choisissez une approche plutôt que l'autre, repère . Et assurez-vous de choisir celui qui a le plus de sens pour vous.
1 votes
Avez-vous besoin du correspondant
content
pour la ligne ?0 votes
Oui, et cela ne pose aucun problème, j'ai supprimé de nombreuses colonnes que je rajouterais.
1 votes
@MarkByers J'ai modifié ma réponse pour répondre aux besoins du PO. Puisque j'y étais, j'ai décidé d'écrire une réponse plus complète sur le site de l'OP. le plus grand-n par-groupe sujet.
2 votes
C'est courant le plus grand-n par-groupe qui a fait l'objet de tests et de des solutions optimisées . Je préfère le solution de jointure gauche par Bill Karwin (le poste original ). Notez que de nombreuses solutions à ce problème courant peuvent étonnamment être trouvées dans l'une des sources les plus officielles, Manuel MySQL ! Voir Exemples de requêtes courantes : : Les lignes contenant le maximum groupé d'une certaine colonne .
2 votes
Duplicata de Récupérer le dernier enregistrement de chaque groupe
0 votes
Pour moi
SELECT DISTINCT ON .... ORDER BY "UserId", "Deals".position;
a mieux fonctionné0 votes
Jetez un coup d'oeil à ça : fr.wikipedia.org/wiki/Relational_database "Chaque ligne d'une table a sa propre clé unique." Y a-t-il une raison particulière pour laquelle vous ne tenez pas compte de cette partie de la spécification ?
0 votes
@HoldOffHunger Je ne le suis pas. Dans le schéma lié vous pouvez voir que j'ai une clé primaire.
0 votes
Il ne semble pas que vous puissiez utiliser quelque chose de standard comme
AUTO_INCREMENT
avec deux champs -- dba.stackexchange.com/q/35449 . Cela en fait un élément très peu standard ; si je ne peux pas incrémenter sa position, quelle est l'utilité d'une position unique ?0 votes
@HoldOffHunger dans le contexte de cette question, pouvez-vous penser à un cas d'utilisation où le fait d'avoir cette clé composite d'id et de rev devient un handicap et où une clé à incrémentation automatique pourrait vous éviter ce problème ? Je ne peux pas et c'est tout ce qui compte pour moi. Vous voyez, je ne trouve pas les "normes" aussi convaincantes que vos préoccupations le laissent entendre. Je suis d'avis que les spécifications et les normes sont là pour nous aider à obtenir les résultats que nous recherchons. Elles ne sont pas une obligation.
0 votes
"Est-ce une bonne pratique de toujours avoir une clé primaire entière auto-incrémentée ?" ~ Réponse : "Oui." génie logiciel.stackexchange.com/q/328458 Certaines personnes ne sont pas d'accord, mais leurs raisons ne sont certainement pas les vôtres.