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

Développement SQL Server Discussion :

Requête avec TOP(n)


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Inscrit en
    Mai 2011
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mai 2011
    Messages : 6
    Par défaut Requête avec TOP(n)
    Bonjour,

    je suis nouveau sur le forum mais ce forum est ma "bible" quand j'ai un problème SQL. D'habitude, je recherche si mon problème a déjà été traité et souvent je trouve et je ne pose pas de question. Cette fois, je n'ai pas trouvé de réponse dans les sujets déjà ouvert...

    Sous SQLServer 2005, j'ai une table des ventes structurée comme suit (je simplifie)

    Magasin
    article
    Montant
    date de vente

    Cette table stocke les ventes de tous les magasins pour tous les articles.

    Si je cherche les 10 articles les plus vendus pour un magasin donné (par exemple le magasin de Bordeaux), je fais la requete :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select top(10) with ties article, count(*) as nombre, sum(montant)
    from table_des_ventes
    where magasin='BORDEAUX'
    group by article
    order by nombre desc;
    Ca fonctionne bien.

    Maintenant je voudrais généraliser cette requête pour tous les magasins, c'est à dire avoir pour chaque magasin la liste des 10 articles les plus vendus (mais en ne faisant qu'une seule requête). Bien sûr, si c'est utile, je précise qu'il existe une table des magasins qui donne la liste exhaustive des magasins.

    j'ai essayé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select magasin, top(10) with ties article, count(*) as nombre, sum(montant)
    from table_des_ventes
    group by magasin, article
    order by nombre desc;
    mais ça ne passe pas au niveau de la syntaxe. J'ai essayé également avec des sous-requête mais sans succès non plus.

    Quelqu'un a une idée du comment faire ?
    Merci.

  2. #2
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Bonjour

    vous pouvez faire comme ceci :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    SELECT 
        M.Nom AS Magasin,
        A.article,
        A.Nombre,
    FROM
        Magasin
    CROSS APPLY (
        SELECT TOP(10) WITH TIES 
            article, 
            COUNT(*) AS Nombre
        FROM table_des_ventes T
        WHERE T.idMagasin = M.idMagasin
        ORDER BY Nombre DESC
    )T

  3. #3
    Membre à l'essai
    Inscrit en
    Mai 2011
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mai 2011
    Messages : 6
    Par défaut
    Merci pour la réponse mais la syntaxe ne doit pas être bonne (il doit manquer un group by et je ne vois pas la table A). J'ai rectifié en

    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
    SELECT 
        M.Nom AS Magasin,
        T.article,
        T.Nombre,
    FROM
        Magasin M
    CROSS APPLY (
        SELECT TOP(10) WITH TIES 
            article, 
            COUNT(*) AS Nombre
        FROM table_des_ventes T
        WHERE T.idMagasin = M.idMagasin
        group by article
        ORDER BY Nombre DESC
    )T
    mais ca ne fonctionne pas non plus...

  4. #4
    Membre à l'essai
    Inscrit en
    Mai 2011
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mai 2011
    Messages : 6
    Par défaut
    Super, ça fonctionne avec la syntaxe suivante :

    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
    SELECT 
    M.Nom AS Magasin,
    T.article,
    T.Nombre,
    FROM
    Magasin M
    CROSS APPLY (
    SELECT TOP(10) WITH TIES 
    article, 
    COUNT(*) AS Nombre
    FROM table_des_ventes Tdv
    WHERE Tdv.idMagasin = M.idMagasin
    group by article
    ORDER BY Nombre DESC
    )T
    Merci de votre aide !

  5. #5
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    On peut aussi écrire, surtout si on veut le rang :

    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
    ;WITH
    	CTE AS
    	(
    		SELECT	magasin
    			, article
    			, COUNT(*) AS quantite
    			, SUM(montant) AS montant_total
    			, ROW_NUMBER() OVER(PARTITION BY magasin ORDER BY COUNT(*) DESC) AS rang
    		FROM	dbo.table_des_ventes
    		GROUP	BY magasin, article
    	)
    SELECT	magasin
    	, article
    	, quantite
    	, montant_total
    FROM	CTE
    WHERE	rang <= 10
    @++

  6. #6
    Membre à l'essai
    Inscrit en
    Mai 2011
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mai 2011
    Messages : 6
    Par défaut
    Citation Envoyé par elsuket Voir le message
    On peut aussi écrire, surtout si on veut le rang :

    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
    ;WITH
    	CTE AS
    	(
    		SELECT	magasin
    			, article
    			, COUNT(*) AS quantite
    			, SUM(montant) AS montant_total
    			, ROW_NUMBER() OVER(PARTITION BY magasin ORDER BY COUNT(*) DESC) AS rang
    		FROM	dbo.table_des_ventes
    		GROUP	BY magasin, article
    	)
    SELECT	magasin
    	, article
    	, quantite
    	, montant_total
    FROM	CTE
    WHERE	rang <= 10
    @++
    Ca marche aussi en effet et c'est plus performant en temps de réponse. Par contre, avec le' rang <=10', on perd la notion d'exaequo il me semble (le 'WITH TIES') ?

  7. #7
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    Il manque le GROUP BY dans le CROSS APPLY, mais l'idée reste bien vue :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT		M.magasin
    		, S.article
    		, S.nombre
    FROM		T AS M
    CROSS APPLY	(
    			SELECT	TOP(10) WITH TIES T.article
    				, COUNT(*) AS Nombre
    			FROM	T
    			WHERE	T.Magasin = M.Magasin
    			GROUP	BY T.article
    			ORDER	BY Nombre DESC
    		) AS S
    @++

  8. #8
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Citation Envoyé par elsuket Voir le message
    Il manque le GROUP BY dans le CROSS APPLY,
    Ha oui

    en effet sans le GROUP BY, ça doit marcher beaucoup moins bien

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

Discussions similaires

  1. Requête SELECT imbriquée avec top ACCESS
    Par blind229 dans le forum Langage SQL
    Réponses: 0
    Dernier message: 12/07/2012, 20h32
  2. Réponses: 4
    Dernier message: 15/05/2007, 10h10
  3. Requête avec l'expression Like
    Par Mvu dans le forum ASP
    Réponses: 3
    Dernier message: 02/09/2003, 09h39
  4. problème de requête avec jointures
    Par tinhat dans le forum Requêtes
    Réponses: 7
    Dernier message: 11/08/2003, 10h33
  5. Problème dans requête avec count()
    Par BadFox dans le forum Requêtes
    Réponses: 3
    Dernier message: 08/07/2003, 18h02

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