J'ai une table avec des colonnes ('name', 'maj', 'min', 'patch') pour chaque nom il peut y avoir plusieurs versions majeures / mineures / patch. Pour chaque nom, j'ai besoin d'obtenir les valeurs majeures + mineures pour le «patch» maximum pour ce majeur / mineur.
par exemple table 'data'
SELECT id, name, maj, min, patch FROM data group by name, maj, min order by name, patch desc
Résultat attendu:
|id|name|maj|min|patch| |3 |n1 |1 |0 | 3 | |4 |n2 |1 |0 | 1 | |6 |n2 |2 |0 | 2 |
J'ai seulement réussi à regrouper ces données par ces champs et ordonné mais je ne sais pas pour obtenir uniquement les lignes avec le patch maximum pour chaque majeur / mineur
|id|name|maj|min|patch| |1 |n1 |1 |0 | 1 | |2 |n1 |1 |0 | 2 | |3 |n1 |1 |0 | 3 | |4 |n2 |1 |0 | 1 | |5 |n2 |2 |0 | 1 | |6 |n2 |2 |0 | 2 |
4 Réponses :
La requête suivante se rapproche de ce que vous voulez:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY name, maj, `min` ORDER BY patch DESC) rn
FROM data
)
SELECT id, name, maj, `min`, patch
FROM cte
WHERE rn = 1;
Mais cela n'inclut pas la colonne id , qui ne fait pas partie de la requête d'agrégation . Si vous voulez une approche générale pour inclure toutes les lignes correspondantes, envisagez d'utiliser ROW_NUMBER:
SELECT
name,
maj,
`min`,
MAX(patch) AS patch
FROM data
GROUP BY
name,
maj,
`min`;
Vous pouvez simplement utiliser Clause pour y parvenir Exemple simple
SELECT id, name, maj, min, max(patch) AS max_patch FROM data GROUP BY patch DESC HAVING MAX(patch) >1;
J'espère que cela vous aidera
Non, simplement, vous ne pouvez pas le faire.
Avec NOT EXISTS:
| id | name | maj | min | patch | | --- | ---- | --- | --- | ----- | | 3 | n1 | 1 | 0 | 3 | | 4 | n2 | 1 | 0 | 1 | | 6 | n2 | 2 | 0 | 2 |
Voir le démo .
Résultats:
select t.* from tablename t where not exists ( select 1 from tablename where name = t.name and maj = t.maj and min = t.min and patch > t.patch )
Merci d'avoir partagé le db-fiddle! super utile
Vous pouvez également le faire avec une sous-requête corrélée:
selet t.*
from t
where t.patch = (select max(t2.patch)
from t t2
where t2.name = t.name and
t2.maj = t.maj and
t2.min = t.min
);
Si vous avez une grande base de données, alors un index sur (name, maj, min, patch) code > fournira de bonnes performances.
C'était le plus facile à comprendre pour moi. Merci!
regardez dans la fonction MAX (), cela devrait vous aider ici