web-dev-qa-db-fra.com

obtenir uniquement des lignes avec une valeur de groupe maximale

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)
8
spuppis

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.

11
McNets