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

Requêtes MySQL Discussion :

SELECT DISTINCT sur plusieurs colonnes avec regroupement [MySQL-5.6]


Sujet :

Requêtes MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2006
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 25
    Par défaut SELECT DISTINCT sur plusieurs colonnes avec regroupement
    Bonjour,
    je souhaite faire une requête sur quatre colonnes, contenant des prénoms et des noms parfois similaires, en récupérant tous les éléments qu'une seule fois, le tout regroupé sur une colonne.

    Voici la base :

    ID Dessin1 Dessin2 Dessin3 Dessin4
    1 Edgar Pierre Jacobs
    2 René Sterne Chantal De Spiegeleer
    3 René Sterne
    4 René Sterne
    5 Alain Dodier
    6 Louis Salvérius
    7 Serge Carrère
    8 Peyo
    9 Peyo
    10 Denis Bajram
    11 Roger Leloup
    12 Morris
    13 Morris
    14 José-Luis Munuera Pedro J. Colombo
    15 Morris Michel Janvier
    16 José-Luis Munuera
    17 Pierce
    18 André Taymans
    19 Morris
    20 Ted Benoît
    21 Michel Janvier Morris Frederic Garcia
    22 Antoine Aubin Etienne Schréder


    Si je souhaite récupérer tous les noms (ou prénom) contenant la lettre "s", je fais la requête suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT DISTINCT Dessin1, Dessin2, Dessin3, Dessin4 FROM bd_albums WHERE Dessin1 LIKE "%s%" OR Dessin2 LIKE "%s%" OR Dessin3 LIKE "%s%" OR Dessin4 LIKE "%s%"
    Et voici le résultat :

    No Dessin1 Dessin2 Dessin3 Dessin4
    1 Edgar Pierre Jacobs
    2 René Sterne Chantal De Spiegeleer
    3 René Sterne
    6 Louis Salvérius
    7 Serge Carrère
    10 Denis Bajram
    12 Morris
    14 José-Luis Munuera Pedro J. Colombo
    15 Morris Michel Janvier
    16 José-Luis Munuera
    18 André Taymans
    21 Michel Janvier Morris Frederic Garcia
    22 Antoine Aubin Etienne Schréder

    On peut arriver au constat suivant :
    • Toutes les lignes où il n'y a pas de "s" ont bien été supprimé (4, 5, 8, 9, 11, 13, 17, 19, 20)
    • Le DISTINCT ne s'est pas fait partout. On trouve plusieurs "Morris" dans la colonne Dessin1 parce que le contenu de Dessin2 ou Dessin3 est différent d'une ligne à l'autre (pourquoi ça je ne sais pas).


    Si possible, je souhaiterais que tous les noms soient réunis en une seule colonne. J'ai essayé d'utiliser GROUP BY, LEAST() et GREATEST() en farfouillant à droite et à gauche mais je n'arrive pas à un résultat concluant. Le regroupement se fait sur une colonne en ignorant le contenu des autres. Voici ce que j'aimerais obtenir, pour être plus clair :

    Edgar Pierre Jacobs
    Chantal De Spiegeleer
    René Sterne
    Louis Salvérius
    Serge Carrère
    Denis Bajram
    Morris
    José-Luis Munuera
    André Taymans
    Etienne Schréder

    Est-il possible de grouper l'intégralité de toutes les colonnes sélectionnées ?

    Merci !

    Maxime

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 136
    Par défaut
    Le problème de base c'est que la table est mal conçue...
    Il devrait y avoir une table album_dessin avec une ligne par album et dessinateur, ce qui permet d'une part d'éviter un certain nombre de colonnes vide et d'autre part autorise un nombre indéfini de dessinateur par album (et non limité à 4).
    Tu peux t'en tirer pour ta requête en effectuant la transformation dans une table dérivée :
    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
    SELECT  DISTINCT
            dessin
    FROM    (   SELECT  id
                    ,   1       AS  colonne
                    ,   dessin1 AS  dessin
                FROM    bd_albums
                WHERE   dessin1 IS NOT NULL
                UNION ALL
                SELECT  id
                    ,   2       AS  colonne
                    ,   dessin2 AS  dessin
                FROM    bd_albums
                WHERE   dessin2 IS NOT NULL
                UNION ALL
                SELECT  id
                    ,   3       AS  colonne
                    ,   dessin3 AS  dessin
                FROM    bd_albums
                WHERE   dessin3 IS NOT NULL
                UNION ALL
                SELECT  id
                    ,   4       AS  colonne
                    ,   dessin4 AS  dessin
                FROM    bd_albums
                WHERE   dessin4 IS NOT NULL
            )   album_dessin
    WHERE   dessin  LIKE '%s%'
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 917
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 917
    Par défaut
    Salut à tous.

    En effet, une meilleure conception de votre table vous permettra de trouver plus facilement la solution à votre problème.
    Voici un exemple de ce que l'on peut faire :
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
     
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE `base`
            default character set `latin1`
            default collate       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `test`
    --------------
     
    --------------
    CREATE TABLE `test`
    ( `id`     integer  unsigned not null,
      `dessin` smallint unsigned not null,
      `nom`    varchar(255)      not null default '',
      primary key (`id`,`dessin`)
    ) engine=innoDB
      default charset=latin1 collate=latin1_general_ci
      row_format=compressed
    --------------
     
    --------------
    insert into `test` (`id`,`dessin`,`nom`) values
      ( 1, 1, 'Edgar Pierre Jacobs'),
      ( 2, 1, 'René Sterne'),
      ( 2, 2, 'Chantal De Spiegeleer'),
      ( 3, 1, 'René Sterne'),
      ( 4, 1, 'René Sterne'),
      ( 5, 1, 'Alain Dodier'),
      ( 6, 1, 'Louis Salvérius'),
      ( 7, 1, 'Serge Carrère'),
      ( 8, 1, 'Peyo'),
      ( 9, 1, 'Peyo'),
      (10, 1, 'Denis Bajram'),
      (11, 1, 'Roger Leloup'),
      (12, 1, 'Morris'),
      (13, 1, 'Morris'),
      (14, 1, 'José-Luis Munuera'),
      (14, 2, 'Pedro J. Colombo'),
      (15, 1, 'Morris'),
      (15, 2, 'Michel Janvier'),
      (16, 1, 'José-Luis Munuera'),
      (17, 1, 'Pierce'),
      (18, 1, 'André Taymans'),
      (19, 1, 'Morris'),
      (20, 1, 'Ted Benoît'),
      (21, 1, 'Michel Janvier'),
      (21, 2, 'Morris'),
      (21, 3, 'Frederic Garcia'),
      (22, 1, 'Antoine Aubin'),
      (22, 2, 'Etienne Schréder')
    --------------
     
    --------------
    select * from test
    --------------
     
    +----+--------+-----------------------+
    | id | dessin | nom                   |
    +----+--------+-----------------------+
    |  1 |      1 | Edgar Pierre Jacobs   |
    |  2 |      1 | René Sterne           |
    |  2 |      2 | Chantal De Spiegeleer |
    |  3 |      1 | René Sterne           |
    |  4 |      1 | René Sterne           |
    |  5 |      1 | Alain Dodier          |
    |  6 |      1 | Louis Salvérius       |
    |  7 |      1 | Serge Carrère         |
    |  8 |      1 | Peyo                  |
    |  9 |      1 | Peyo                  |
    | 10 |      1 | Denis Bajram          |
    | 11 |      1 | Roger Leloup          |
    | 12 |      1 | Morris                |
    | 13 |      1 | Morris                |
    | 14 |      1 | José-Luis Munuera     |
    | 14 |      2 | Pedro J. Colombo      |
    | 15 |      1 | Morris                |
    | 15 |      2 | Michel Janvier        |
    | 16 |      1 | José-Luis Munuera     |
    | 17 |      1 | Pierce                |
    | 18 |      1 | André Taymans         |
    | 19 |      1 | Morris                |
    | 20 |      1 | Ted Benoît            |
    | 21 |      1 | Michel Janvier        |
    | 21 |      2 | Morris                |
    | 21 |      3 | Frederic Garcia       |
    | 22 |      1 | Antoine Aubin         |
    | 22 |      2 | Etienne Schréder      |
    +----+--------+-----------------------+
    --------------
    select id,
           max(col1) as 'Dessin N°1',
           max(col2) as 'Dessin N°2',
           max(col3) as 'Dessin N°3',
           max(col4) as 'Dessin N°4'
    from (
        select id,
               case when dessin=1 then nom else '' end as col1,
               case when dessin=2 then nom else '' end as col2,
               case when dessin=3 then nom else '' end as col3,
               case when dessin=4 then nom else '' end as col4
        from test
        order by id, dessin
    ) as x
    group by id
    --------------
     
    +----+---------------------+-----------------------+-----------------+------------+
    | id | Dessin N°1          | Dessin N°2            | Dessin N°3      | Dessin N°4 |
    +----+---------------------+-----------------------+-----------------+------------+
    |  1 | Edgar Pierre Jacobs |                       |                 |            |
    |  2 | René Sterne         | Chantal De Spiegeleer |                 |            |
    |  3 | René Sterne         |                       |                 |            |
    |  4 | René Sterne         |                       |                 |            |
    |  5 | Alain Dodier        |                       |                 |            |
    |  6 | Louis Salvérius     |                       |                 |            |
    |  7 | Serge Carrère       |                       |                 |            |
    |  8 | Peyo                |                       |                 |            |
    |  9 | Peyo                |                       |                 |            |
    | 10 | Denis Bajram        |                       |                 |            |
    | 11 | Roger Leloup        |                       |                 |            |
    | 12 | Morris              |                       |                 |            |
    | 13 | Morris              |                       |                 |            |
    | 14 | José-Luis Munuera   | Pedro J. Colombo      |                 |            |
    | 15 | Morris              | Michel Janvier        |                 |            |
    | 16 | José-Luis Munuera   |                       |                 |            |
    | 17 | Pierce              |                       |                 |            |
    | 18 | André Taymans       |                       |                 |            |
    | 19 | Morris              |                       |                 |            |
    | 20 | Ted Benoît          |                       |                 |            |
    | 21 | Michel Janvier      | Morris                | Frederic Garcia |            |
    | 22 | Antoine Aubin       | Etienne Schréder      |                 |            |
    +----+---------------------+-----------------------+-----------------+------------+
    --------------
    select distinct nom from test where nom like '%s%'
    --------------
     
    +-----------------------+
    | nom                   |
    +-----------------------+
    | Edgar Pierre Jacobs   |
    | René Sterne           |
    | Chantal De Spiegeleer |
    | Louis Salvérius       |
    | Serge Carrère         |
    | Denis Bajram          |
    | Morris                |
    | José-Luis Munuera     |
    | André Taymans         |
    | Etienne Schréder      |
    +-----------------------+
    --------------
    commit
    --------------
     
    --------------
    set autocommit = 1
    --------------
     
     
    Appuyez sur une touche pour continuer...
    @+

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Février 2006
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 25
    Par défaut
    Cette base de données est strictement personnelle et me permet de répertorier mes bandes dessinées (comme vous l'avez sans doute remarqué). C'est la raison pour laquelle je n'ai fait que deux tables, une pour les séries, une autre pour les albums.

    Je conçois que la table est mal conçue, mais je ne voyais pas, jusqu'à aujourd'hui, l'utilité de multiplier les tables. Néanmoins, je me sers de la requête pour une autocomplétion de mes champs (dessin, scénario, éditeur...) lors de l'ajout d'albums. Autocomplétion qui me sert à grandement accélérer l'ajout de nouvel album et de ne pas faire d'erreurs de saisie.
    Or, quand je commence à taper des lettres, je rencontre plusieurs problèmes dont deux principaux :

    • plusieurs fois le même nom
    • et surtout un autre plus ennuyeux, si je tape "Spiegeleer", par exemple, le champ ne va pas m'afficher "Chantal De Spiegeleer" mais "René Sterne"


    D'après vos réponses, la meilleure solution est de multiplier les tables. Je n'avais pas vu la solution sous cet angle, mais, en effet, ça peut définitivement régler les problèmes que je rencontre lors de l'autocomplétion.

    Merci d'avoir pris le temps de me répondre.

  5. #5
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 917
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 917
    Par défaut
    Salut lofo7.

    Citation Envoyé par lofo7
    Je conçois que la table est mal conçue, mais je ne voyais pas, jusqu'à aujourd'hui, l'utilité de multiplier les tables.
    Nous avons dit qu'en fonction du traitement que vous désirez faire, la table n'était pas du tout adaptée.

    Citation Envoyé par lofo7
    Or, quand je commence à taper des lettres, je rencontre plusieurs problèmes dont deux principaux :
    • plusieurs fois le même nom
    • et surtout un autre plus ennuyeux, si je tape "Speigeleer", par exemple, le champ ne va pas m'afficher "Chantal De Spiegeleer" mais "René Sterne"
    Vous êtes obligé de passer par l'organisation de votre base de donnée, en formulant vos besoins.

    Pour résoudre la duplication du même nom, et bien vous créez une table des auteurs.
    Ensuite, dans vos autres tables, par exemple, les albums, vous faites un lien vers la table des auteurs, que l'on nomme une clef étrangère.
    Mais un album n'est pas fait par un seul auteur. Dans ce cas, la clef étrangère n'est plus du tout adaptée.
    Dans le cas, il faut créer une table association entre les tables auteurs et albums.

    Le mieux est de discuter de cela dans le forum consacré à Merise : http://www.developpez.net/forums/f96...-sgbd/debuter/

    Après la modélisation de votre base de données, si vous avez des questions de faisabilité, vous pouvez revenir ici poser vos questions.

    @+

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Février 2006
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 25
    Par défaut
    Pour résoudre la duplication du même nom, et bien vous créez une table des auteurs.
    Ensuite, dans vos autres tables, par exemple, les albums, vous faites un lien vers la table des auteurs, que l'on nomme une clef étrangère.
    Mais un album n'est pas fait par un seul auteur. Dans ce cas, la clef étrangère n'est plus du tout adaptée.
    Dans le cas, il faut créer une table association entre les tables auteurs et albums.
    C'est exactement ce que je suis en train de faire. Je me suis créé une table auteurs, une table scénarios, dessins, etc. L'autocomplétion sera ainsi grandement facilitée. Et comme vous l'indiquez, je me suis aussi créé une table d'association. C'est plus long mais beaucoup plus logique.

    Merci d'avoir pris le temps de me conseiller !

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

Discussions similaires

  1. Filtres sur plusieurs colonnes avec OU
    Par JackIsJack dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 30/05/2011, 16h40
  2. distinct sur plusieurs colonnes
    Par zerocoolyoussef dans le forum Langage SQL
    Réponses: 4
    Dernier message: 12/08/2009, 12h23
  3. faire un distinct sur plusieurs colonnes
    Par elekis dans le forum Langage SQL
    Réponses: 4
    Dernier message: 30/03/2009, 13h23
  4. Etat sur plusieurs colonnes avec saut de section
    Par Binpush dans le forum IHM
    Réponses: 4
    Dernier message: 26/02/2009, 14h54
  5. Query sur plusieurs colonnes avec count(distinct...)
    Par Jeankiki dans le forum Langage SQL
    Réponses: 2
    Dernier message: 18/08/2004, 15h22

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