IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MS SQL Server Discussion :

TOP N sur un GROUP BY


Sujet :

MS SQL Server

  1. #1
    Membre habitué Avatar de GodGives
    Inscrit en
    Août 2007
    Messages
    456
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Août 2007
    Messages : 456
    Points : 161
    Points
    161
    Par défaut TOP N sur un GROUP BY
    bonjour à tous!

    je dispose de 20 produits et de 60 clients. J'aimerais écrire une requête qui me sort les 3 meilleurs clients par produits.

    J'ai pu écrire une requête qui me donne le chiffre d'affaire par ordre décroissant par produit et par clients:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select codprod, codcli, sum(montant) as ca
    from factures group by codprod, codcli
    order by codprod asc, codcli desc
    ceci me donne le résultat suivant:
    prod_1 ______ cli_6 ______ 3 000 000
    prod_1 ______ cli_5 ______ 2 700 000
    prod_1 ______ cli_3 ______ 2 550 000
    prod_1 ______ cli_9 ______ 2 490 000
    prod_1 ______ cli_2 ______ 2 370 000
    prod_1 ______ cli_7 ______ 2 290 000
    prod_1 ______ cli_1 ______ 2 270 000
    prod_1 ______ cli_4 ______ 1 850 000
    prod_1 ______ cli_8 ______ 1 650 000

    prod_2 ______ --- ______ ---
    prod_2 ______ --- ______ ---
    prod_2 ______ --- ______ ---
    prod_2 ______ --- ______ ---
    prod_2 ______ --- ______ ---
    prod_2 ______ --- ______ ---
    prod_2 ______ --- ______ ---
    prod_2 ______ --- ______ ---
    prod_2 ______ --- ______ ---

    prod_3 ______ --- ______ ---
    prod_3 ______ --- ______ ---
    prod_3 ______ --- ______ ---
    prod_3 ______ --- ______ ---
    prod_3 ______ --- ______ ---
    prod_3 ______ --- ______ ---
    prod_3 ______ --- ______ ---
    prod_3 ______ --- ______ ---
    prod_3 ______ --- ______ ---

    Quand je met le TOP 3 au debut de la requête, j'ai comme résultat, les 3 lignes correspondant au 3 premiers clients du premier produit alors que je veux avoir par produit, les 3 meilleurs.

    Y-a t-il une autre manière d'utiliser le top n de façon à avoir ce que veux?

  2. #2
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Bonjour,

    Essayez ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    WITH CTE
    AS
    (
     SELECT 
      codeprod, 
      codecli, 
      SUM(montant) AS ca,
      RANK() OVER(PARTITION BY codeprod  ORDER BY SUM(montant) DESC) AS num
    FROM @factures 
    GROUP BY codeprod, codecli
    )
    SELECT *
    FROM CTE
    WHERE num <= 3
    ++

  3. #3
    Membre habitué Avatar de GodGives
    Inscrit en
    Août 2007
    Messages
    456
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Août 2007
    Messages : 456
    Points : 161
    Points
    161
    Par défaut
    Quand je met cette requête dans l'analyseur de requête de mon sql serveur 2000, j'ai l'erreur suivante:
    Serveur*: Msg 195, Niveau 15, État 10, Ligne 2
    'RANK' n'est pas un nom de fonction reconnu.

  4. #4
    Membre habitué Avatar de GodGives
    Inscrit en
    Août 2007
    Messages
    456
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Août 2007
    Messages : 456
    Points : 161
    Points
    161
    Par défaut
    Citation Envoyé par mikedavem Voir le message
    Bonjour,
    RANK() OVER(PARTITION BY codeprod ORDER BY SUM(montant) DESC) AS num
    ++
    la syntaxe est tout à fait correcte; je crains que sa non reconnaissance à mon niveau ne soit dû à la version de mon sql server.

  5. #5
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Pourquoi j'étais sûr que vous étiez sur SQL Server 2000 et que la fonction RANK() ne fonctionnerait pas ...

    Quelque chose comme ceci devrait fonctionner :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    SELECT *
    FROM
    (
      SELECT 
       *,
       (SELECT COUNT(*)
        FROM 
        (
          SELECT 
    	   codeprod, 
    	   codecli, 
    	   SUM(montant) AS ca
          FROM @factures 
          GROUP BY codeprod, codecli
         ) T2
         WHERE T2.codeprod = T1.codeprod  
          AND T2.ca > T1.ca
       ) [rank]
      FROM
      (
    	SELECT 
    	  codeprod, 
    	  codecli, 
    	  SUM(montant) AS ca
    	FROM @factures AS T1
    	GROUP BY codeprod, codecli
      ) AS T1
    ) AS T3
    WHERE T3.rank < 2
    ORDER BY T3.codeprod, T3.rank
    ++

  6. #6
    Membre habitué Avatar de GodGives
    Inscrit en
    Août 2007
    Messages
    456
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Août 2007
    Messages : 456
    Points : 161
    Points
    161
    Par défaut
    J'avoue que j'ai pris plus de 3 heures pour comprendre comment elle fonctionne afin de l'adapter à ma situation et je suis heureux de voir que cela a fonctionné.

    Merci beaucoup mikedavem!!!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] Question sur les GROUP BY
    Par Coladin dans le forum Langage SQL
    Réponses: 5
    Dernier message: 21/04/2006, 14h25
  2. Réponses: 2
    Dernier message: 11/04/2006, 16h09
  3. Top 10 sur plusieurs items
    Par hussard dans le forum Langage SQL
    Réponses: 1
    Dernier message: 03/10/2005, 09h33
  4. Théorie sur les groupes et les ensembles
    Par grav dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 02/02/2005, 18h24
  5. Aide sur les groupes (ADO)
    Par portu dans le forum QuickReport
    Réponses: 3
    Dernier message: 18/08/2004, 16h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo