1
votes

Requête SQL avec plusieurs colonnes et une fonction d'agrégation à l'aide de GROUP BY

J'ai des problèmes avec ma requête SQL. J'ai la table movie suivante:

GENRE                          MAX(M.BUDGET) TITLE
------------------------------ ------------- ------------------------------
Western                              1200000 The Good, the Bad and the Ugly
Horror                                806947 Psycho
Crime                                7000000 The Godfather: Part III
Action                             185000000 The Dark Knight
Drama                               26000000 Philadelphia
Drama                               13000000 In the Name of the Father
Action                             150000000 Batman Begins
Historical                          23800000 The Last Emperor
Science-fiction                      5800000 Planet of the Apes
Crime                                7000000 The Godfather
Action                             230000000 The Dark Knight Rises

GENRE                          MAX(M.BUDGET) TITLE
------------------------------ ------------- ------------------------------
Comedy                              28000000 Zoolander
Crime                                9000000 Pulp Fiction
Crime                               13000000 The Godfather: Part II
War                                 70000000 Saving Private Ryan
Science-fiction                     28000000 Blader Runner
Drama                               33000000 Gran Torino

j'ai essayé cette commande: sélectionnez m.genre, max (m.budget), m.title du film m group par m.genre, m.title; et j'ai obtenu ce résultat:

 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID_MOVIE                                  NOT NULL NUMBER(4)
 TITLE                                     NOT NULL VARCHAR2(30)
 GENRE                                     NOT NULL VARCHAR2(30)
 YEAR                                      NOT NULL NUMBER(4)
 COUNTRY                                   NOT NULL VARCHAR2(30)
 DURATION                                  NOT NULL NUMBER(3)
 BUDGET                                             NUMBER(10)
 INCOMES                                            NUMBER(10)
 ID_MOVIE_PREV                                      NUMBER(4)
 ID_DIRECTOR

Je voudrais avoir le titre du maximum de chaque sexe. Quelqu'un peut-il me dire où est mon erreur? Merci d'avance!


1 commentaires

Voulez-vous dire le genre au lieu du genre?


3 Réponses :


0
votes

Vous pouvez utiliser la fonction d'analyse row_number () :

select genre, budget,title
  from
  (
      select genre, budget, title,
             row_number() over (partition by genre order by budget desc) as rn       
        from movie 
   )
  where rn = 1

le regroupement est effectué par partition par et la valeur maximale du budget est trouvée en triant par budget décroissant.

/ p>

Démo p >


1 commentaires

À quoi sert "q. *" Ou comment s'appelle-t-il cette fonction?



1
votes

Je soupçonne que votre requête ne s'agrège pas réellement, car vous vous attendez à ce que les tuples (genre, titre) soient uniques dans la table.

Vous pouvez utiliser une sous-requête corrélée pour filtrer la table :

GENRE           | TITLE                          |    BUDGET
:-------------- | :----------------------------- | --------:
Western         | The Good, the Bad and the Ugly |   1200000
Horror          | Psycho                         |    806947
Historical      | The Last Emperor               |  23800000
Action          | The Dark Knight Rises          | 230000000
Comedy          | Zoolander                      |  28000000
Crime           | The Godfather: Part II         |  13000000
War             | Saving Private Ryan            |  70000000
Science-fiction | Blader Runner                  |  28000000
Drama           | Gran Torino                    |  33000000

Cela me semble être le moyen le plus simple d'exprimer ce que vous essayez d'accomplir. Pour les performances, pensez à un index sur (genre, budget) .

Voici un démo sur DB Fiddle (basé sur l'hypothèse ci-dessus que votre ensemble de résultats actuel peut être considéré comme vos données brutes):

select genre,title, budget
from movie m
where budget = (
    select max(m1.budget)
    from movie m1
    where m1.genre = m.genre
)


0 commentaires

0
votes

Dans Oracle, vous pouvez utiliser l'agrégation:

select genre,
       max(title) keep (dense_rank first order by budget desc) as title,
       max(budget) as budget
from movie m
group by genre;

L'expression keep fait essentiellement une fonction get-the-first-value.


0 commentaires