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 :

Retourner des lignes complètes avec un distinct sur un champ, est-ce possible ?


Sujet :

Développement SQL Server

  1. #1
    Membre régulier Avatar de Stephane_br
    Inscrit en
    Septembre 2005
    Messages
    222
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 222
    Points : 83
    Points
    83
    Par défaut Retourner des lignes complètes avec un distinct sur un champ, est-ce possible ?
    Bonjour,

    Je suis un peu perdu. J'ai besoin de retourner par une requête, certaines infos mais je ne comprend pas le fonctionnement du GROUP BY/DISTINCT. Pourriez-vous m'aider s'il vous plait ?

    En fait voilà. j'ai une base PRODUITS avec par exemple les champs suivants :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    ID (int)
    Cat (int)
    Nom (nvarchar(250))
    Descr (ntext)
    Img (nvarchar(50))
    Tarif (float)
    Actif (bit)
    GroupNom (nvarchar(250))
    GroupClassement (int)
    Elle contient par exemple :
    ID / Cat / Nom / Descr / Img / Tarif / Actif / GroupNom / GroupClassement
    1 / 1 / peugeot 307 / 3 portes... / p307.jpg / 5000.00 / 1 / PEUGEOT / 3
    2 / 1 / peugeot 207 / 5 portes... / p207.jpg / 4000.00 / 0 / PEUGEOT / 2
    3 / 1 / peugeot 407 / 5 portes... / p407.jpg / 7000.00 / 1 / PEUGEOT / 1
    4 / 1 / Citroen C5 / 5 portes... / CC5.jpg / 3000.00 / 1 / CITROEN / 2
    5 / 1 / Citroen C1 / 3 portes... / CC1.jpg / 7000.00 / 0 / CITROEN / 1
    6 / 1 / Ford Fiesta / 3 portes... / ff.jpg / 3000.00 / 1 / FORD / 1



    J'aimerais que ma requête me retourne les lignes complètes mais en faisant un distinct sur la colonne GroupNom et faisant un order by GroupClassement DESC de manière à récupérer les infos du produit le mieux classé dans le GroupNom.
    > Par exemple, le résultat que j'attends est celui-ci :



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    1 / 1 / peugeot 307 / 3 portes... / p307.jpg / 5000.00 / 1 / PEUGEOT / 3
    4 / 1 / Citroen C5 / 5 portes... / CC5.jpg / 3000.00 / 1 / CITROEN  / 2
    6 / 1 / Ford Fiesta / 3 portes... / ff.jpg / 3000.00 / 1 / FORD / 1

    Je ne vois pas comment obtenir ce résultat ni par un distinct, ni en utilisant group by.
    Est-ce possible de faire cela en une seule requête seulement ? Ou peut être en plusieurs requêtes imbriqués en une ?

    Merci pour toute votre aide.

  2. #2
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    733
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2003
    Messages : 733
    Points : 1 668
    Points
    1 668
    Billets dans le blog
    8
    Par défaut
    Ci-dessous le requête SQL répondant à ta demande :

    Script de création et de peuplement de la table :
    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
    CREATE TABLE PRODUITS 
    (ID int not null CONSTRAINT  PK_PRODUITS primary key, 
     Cat int not null, 
     Nom nvarchar(250) not null, 
     GroupNom nvarchar(250) not null, 
     GroupClassement int not null
    ) 
    GO
     
    INSERT INTO PRODUITS 
    VALUES 
     (1, 1, 'peugeot 307', 'PEUGEOT', 3), 
     (2, 1, 'peugeot 207', 'PEUGEOT', 2), 
     (3, 1, 'peugeot 407', 'PEUGEOT', 1), 
     (4, 1, 'Citroen C5' , 'CITROEN', 2), 
     (5, 1, 'Citroen C1' , 'CITROEN', 1), 
     (6, 1, 'Ford Fiesta', 'FORD', 1); 
    GO
    Requête SQL pour obtenir le résultat attendu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT DISTINCT A.*  
     FROM PRODUITS A 
     WHERE A.GroupClassement = (SELECT MAX(B.GroupClassement) 
                                FROM PRODUITS B 
                                WHERE B.GroupNom = A.GroupNom) 
    ORDER BY A.GroupClassement  DESC             
    GO
    Résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ID	Cat	Nom	GroupNom	GroupClassement
    1	1	peugeot 307	PEUGEOT	3
    4	1	Citroen C5	CITROEN	2
    6	1	Ford Fiesta	FORD	1
    A+
    "Une idée mal écrite est une idée fausse !"
    http://hamid-mira.blogspot.com

  3. #3
    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 : 45
    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
    Bonsoir,

    Pour le fun une autre approche en complément de celle proposée par hmira (et si vous êtes au moins sur une version 2005) :

    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
    31
    32
    WITH T
    AS
    (
      SELECT 1 AS ID, 1 AS Cat, 'peugeot 307' AS Nom, 'PEUGEOT' AS GroupNom, 3 AS GroupClassement
      UNION ALL 
      SELECT 2, 1, 'peugeot 207', 'PEUGEOT', 2 
      UNION ALL
      SELECT 3, 1, 'peugeot 407', 'PEUGEOT', 1
      UNION ALL 
      SELECT 4, 1, 'Citroen C5' , 'CITROEN', 2
      UNION ALL 
      SELECT 5, 1, 'Citroen C1' , 'CITROEN', 1
      UNION ALL
      SELECT 6, 1, 'Ford Fiesta', 'FORD', 1
    ),
    NUM
    AS
    (
    	SELECT 
    	ROW_NUMBER() OVER(PARTITION BY GroupNom ORDER BY GroupClassement DESC) AS num,
    	*
    	FROM T
    )
    SELECT 
     ID,
     Cat,
     Nom,
     GroupNom,
     GroupClassement
    FROM NUM
    WHERE num = 1
    ORDER BY ID
    ++

  4. #4
    Membre régulier Avatar de Stephane_br
    Inscrit en
    Septembre 2005
    Messages
    222
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 222
    Points : 83
    Points
    83
    Par défaut
    Citation Envoyé par hmira Voir le message
    Ci-dessous le requête SQL répondant à ta demande :

    Script de création et de peuplement de la table :
    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
    CREATE TABLE PRODUITS 
    (ID int not null CONSTRAINT  PK_PRODUITS primary key, 
     Cat int not null, 
     Nom nvarchar(250) not null, 
     GroupNom nvarchar(250) not null, 
     GroupClassement int not null
    ) 
    GO
     
    INSERT INTO PRODUITS 
    VALUES 
     (1, 1, 'peugeot 307', 'PEUGEOT', 3), 
     (2, 1, 'peugeot 207', 'PEUGEOT', 2), 
     (3, 1, 'peugeot 407', 'PEUGEOT', 1), 
     (4, 1, 'Citroen C5' , 'CITROEN', 2), 
     (5, 1, 'Citroen C1' , 'CITROEN', 1), 
     (6, 1, 'Ford Fiesta', 'FORD', 1); 
    GO
    Requête SQL pour obtenir le résultat attendu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT DISTINCT A.*  
     FROM PRODUITS A 
     WHERE A.GroupClassement = (SELECT MAX(B.GroupClassement) 
                                FROM PRODUITS B 
                                WHERE B.GroupNom = A.GroupNom) 
    ORDER BY A.GroupClassement  DESC             
    GO
    Résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ID	Cat	Nom	GroupNom	GroupClassement
    1	1	peugeot 307	PEUGEOT	3
    4	1	Citroen C5	CITROEN	2
    6	1	Ford Fiesta	FORD	1
    A+
    Merci pour ta réponse.
    J'ai essayé et en effet ça fonctionne.
    Cependant, j'aimerais comprende (ce n'est pas le cas actuellement )
    Peut-tus m'expliquer s'il te plait c'est quoi A et B ? d'où ça sort ?
    Et ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT DISTINCT A.*  
     FROM PRODUITS A
    Pourquoi as-tu mis ça ?
    Merci par avance.

    PS: Si le champ GroupNom est vide, ça ne me remonte pas la ligne concernée. Est-ce normal ?

  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 : 45
    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
    Les "A" sont des ALIAS.

    Ce mécanisme permet, en autre, de simplifier l'écriture du code et dans votre cas de distinguer la table PRODUITS de la requête et de la sous requête.

    ++

  6. #6
    Membre régulier Avatar de Stephane_br
    Inscrit en
    Septembre 2005
    Messages
    222
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 222
    Points : 83
    Points
    83
    Par défaut
    Merci beaucou pour votre aide.
    C'est niquel

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

Discussions similaires

  1. [AC-2007] Problème avec COUNT DISTINCT sur plusieurs champs :
    Par Bonero dans le forum Requêtes et SQL.
    Réponses: 7
    Dernier message: 12/10/2012, 14h33
  2. Affichage des lignes d'une table si AU MOINS Champ est NON VIDE
    Par Dr_No dans le forum Requêtes et SQL.
    Réponses: 5
    Dernier message: 09/07/2009, 17h47
  3. Réponses: 7
    Dernier message: 02/02/2009, 20h04
  4. determiner si une requete retourne des lignes
    Par sundjata dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 25/07/2006, 00h19
  5. Retourné des lignes dont certains champs sont vides
    Par griese dans le forum Langage SQL
    Réponses: 5
    Dernier message: 27/06/2006, 10h23

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