2 votes

Retour maximal de toutes les valeurs dans une jointure automatique

Pour mon problème, je dois interroger les données de la table et inclure une colonne pour calculer le pourcentage d'augmentation. Je dois extraire uniquement les enregistrements présentant le pourcentage d'augmentation le plus élevé en utilisant MAX. Je pense être sur la bonne voie, mais pour une raison quelconque, tous les enregistrements sont renvoyés alors que la clause having ne demande que le maximum.

Select
  O.Grocery_Item,
  TO_CHAR(sum(g.Price_IN_2000), '$99,990.00') TOTAL_IN_2000,
  TO_CHAR(sum(g.Estimated_Price_In_2025), '$99,990.00') TOTAL_IN_2025,
  TO_CHAR(Round(O.MY_OUTPUT),'9,990') || '%' as My_Output
From
  GROCERY_PRICES g,
  (SELECT
     GROCERY_ITEM,
     (((sum(Estimated_Price_In_2025) -
        sum(Price_IN_2000))/sum(Price_IN_2000))*100) MY_OUTPUT
   FROM
     GROCERY_PRICES
   GROUP BY GROCERY_ITEM) O
Where
  G.GROCERY_ITEM = O.GROCERY_ITEM 
GROUP BY
  O.GROCERY_ITEM, O.MY_OUTPUT
Having
  my_output IN (select Max(O.MY_OUTPUT) from GROCERY_PRICES);

Résultats :

GROCERY_ITEM                   TOTAL_IN_2000 TOTAL_IN_2025 MY_OUTPUT
------------------------------ ------------- ------------- ---------
M_004                                $2.70         $5.65      109%   
B_001                                $0.80         $2.64      230%   
T_006                                $5.70         $6.65       17%   
B_002                                $2.72         $7.36      171%   
E_001                                $0.62         $1.78      187%   
R_003                                $4.00        $13.20      230%   

 6 rows selected

1voto

GarethD Points 30173

Vous pouvez simplifier votre requête en ne sélectionnant qu'une seule fois dans la table Groceries, car vos My_Output est uniquement fonction des chiffres que vous produisez déjà, l'auto-jonction n'est pas nécessaire. Ensuite, j'ai utilisé RANK pour obtenir les meilleurs enregistrements (bien que si vous n'êtes pas concerné par les égalités, ROWNUM fonctionnera mieux) :

SELECT  g.Grocery_Item,
        g.TOTAL_IN_2000,
        g.TOTAL_IN_2025,
        g.My_Output
FROM    (   SELECT  Grocery_Item,
                    TO_CHAR(TOTAL_IN_2000, '$99,990.00') TOTAL_IN_2000,
                    TO_CHAR(TOTAL_IN_2025, '$99,990.00') TOTAL_IN_2025,
                    TO_CHAR(ROUND(((TOTAL_IN_2025 / TOTAL_IN_2000) - 1) * 100), '9,990') || '%' as My_Output,
                    RANK() OVER(PARTITION BY Grocery_Item ORDER BY (TOTAL_IN_2025 / TOTAL_IN_2000) - 1 DESC) AS GroceryRank
            FROM    (   SELECT  g.Grocery_Item,
                                SUM(g.Price_IN_2000) TOTAL_IN_2000,
                                SUM(g.Estimated_Price_In_2025) TOTAL_IN_2025
                        FROM    GROCERY_PRICES g
                        GROUP BY g.Grocery_Item
                    ) g
        ) g
WHERE   GroceryRank = 1;

J'ai également simplifié votre calcul du pourcentage.

0voto

Gordon Linoff Points 213350

Essayez plutôt ceci :

select *
from (Select O.Grocery_Item, TO_CHAR(sum(g.Price_IN_2000), '$99,990.00') TOTAL_IN_2000,
             TO_CHAR(sum(g.Estimated_Price_In_2025), '$99,990.00') TOTAL_IN_2025,
             TO_CHAR(Round(O.MY_OUTPUT),'9,990') || '%' as My_Output
      From GROCERY_PRICES g join
           (SELECT GROCERY_ITEM,
                   (((sum(Estimated_Price_In_2025) -
                    sum(Price_IN_2000))/sum(Price_IN_2000))*100
                    ) MY_OUTPUT
            FROM GROCERY_PRICES
            GROUP BY GROCERY_ITEM
           ) O
           on G.GROCERY_ITEM = O.GROCERY_ITEM 
      GROUP BY O.GROCERY_ITEM, O.MY_OUTPUT
      ORDER BY my_output desc
     ) t
where rownum = 1

Le problème est que votre sous-requête n'a que des références externes. Ainsi, la o.my_output provient de la table externe, et non de la from dans la sous-requête. Vous comparez une valeur à elle-même, ce qui est toujours vrai pour les valeurs non NULL.

Puisque vous voulez la valeur maximale, le plus simple est d'ordonner la liste et de prendre la première ligne. Vous pouvez également le faire avec des fonctions analytiques, mais rownum est généralement plus efficace.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X