1
votes

SQL: filtre (lignes) avec une valeur maximale dans les groupes (colonnes)

Je dois filtrer les lignes en fonction des valeurs maximales de version dans le mois et dans le lieu. Utilisation de SQL.

Par exemple, j'ai le tableau ci-dessous où il y a les versions 1 et 2 de June & NYC, je voulais filtrer uniquement la ligne de la version 2 avec des revenus 11. Ou pour janvier & NYC, je voulais obtenir uniquement la ligne avec revenu 15.

Month   Location  Version   Revenue
June    NYC        2          11
June    LA         3          12
January NYC        3          15
January LA         2          17

Résultat:

Month   Location Version    Revenue
June    NYC     1            10
June    NYC     2            11
June    LA      3            12
January NYC     1            13
January NYC     2            14
January NYC     3            15
January LA      1            16
January LA      2            17

Modifiez pour changer le nom de la colonne en Revenu afin d'éliminer toute confusion . Je n'ai pas besoin de la valeur maximale des revenus, mais uniquement des revenus correspondant à la version maximale de ce mois et de cet emplacement.

sql

4 commentaires

La ligne de janvier NYC dans le résultat devrait-elle avoir 15 pour la valeur? Cela semble être le modèle (valeur maximale). La section Résultat affiche les 3 et 14 janvier NYC (par opposition au 15).


Je relis la question et je suis confus. Voulez-vous, pour un mois et un emplacement donnés, les colonnes Max Version et Value? C'est ce que le résultat semble montrer, mais le texte demande une valeur maximale. Pouvez-vous clarifier ce que vous demandez?


Mes excuses pour la confusion, j'ai changé le nom de la colonne de valeur en revenu. Je n'ai besoin que de la version maximale et des revenus qui en découlent.


OK - dans ce cas, je pense que vous voulez la réponse à la sous-requête corrélée alors. Je supprimerai ma réponse.


3 Réponses :


0
votes

Une méthode typique consiste à filtrer à l'aide d'une sous-requête corrélée:

select t.*
from t
where t.version = (select max(t2.version)
                   from t t2
                   where t2.month = t.month and t2.location = t.location
                  );


0 commentaires

1
votes

Vous pouvez également utiliser des jointures comme alternative aux sous-requêtes corrélées, par exemple:

select t1.* from YourTable t1 inner join
(
    select t2.month, t2.location, max(t2.version) as mv
    from YourTable t2
    group by t2.month, t2.location
) q on t1.month = q.month and t1.location = q.location and t1.version = q.mv

Remplacez YourTable par le nom de votre table.

p>


1 commentaires

C'est la réponse parfaite. Merci beaucoup!



0
votes

Une autre alternative qui minimise les sous-requêtes est d'utiliser la fonction de fenêtre row_number () . (Vous ne mentionnez pas quel serveur de base de données que vous utilisez, mais la plupart d’entre eux le prennent en charge.)

SELECT month, location, version, revenue
FROM (SELECT month, location, version, revenue
           , row_number() OVER (PARTITION BY month, location ORDER BY version DESC) AS rn
      FROM your_table)
WHERE rn = 1;


0 commentaires