par exemple, nous avons:
element | group_value | value
a | 1 | 2000
a | 2 | 1500
a | 2 | 2500
b | 1 | 1000
Je voudrais renvoyer uniquement les 3 derniers enregistrements car ce sont les enregistrements avec la valeur de groupe maximale pour chaque élément.
Je connais une solution avec sous-requête, mais y a-t-il une solution efficace?
Pour clarifier: pour l'élément 'a':
2 étant la valeur de groupe la plus élevée, il renvoie les lignes 2 et 3> (et non la première ligne car sa valeur de groupe n'est pas la plus élevée),
pour l'élément "b":
1 est> valeur_groupe la plus élevée, il renvoie donc la ou les lignes 4
Ma (performance-vice pas bonne) solution au problème est:
select *
from x x1
where (element, group_value) in (select element, max(group_value)
from x x2
where x1.element = x2.element
group by x2.element)
La première réponse utilise un CTE pour sélectionner max (valeur_groupe), puis rejoindre la table.
with maxgv as
(
select element, max(group_value) maxg
from x
group by element
)
select x.element, x.group_value, x.value
from maxgv
inner join x
on x.element = maxgv.element
and x.group_value = maxgv.maxg
;
Celui-ci utilise la fonction RANK ():
with grp as
(
select element, group_value, value,
rank() over (partition by element order by element, group_value desc) rn
from x
)
select element, group_value, value
from grp
where rn = 1;
Les deux renvoient le même résultat:
| element | group_value | value | |---------|-------------|-------| | a | 2 | 1500 | | a | 2 | 2500 | | b | 1 | 1000 |
Rextester ici
Mais, juste pour vérifier et comparer les performances, nous avons besoin du schéma de table. Je ne sais pas quel index utilise votre requête actuelle.