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 :

Concaténation de plusieurs valeurs d'une colonne.


Sujet :

Requêtes MySQL

  1. #1
    Membre à l'essai
    Inscrit en
    Août 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 16
    Points : 12
    Points
    12
    Par défaut Concaténation de plusieurs valeurs d'une colonne.
    Bonjour à tous,

    Voici mon problème: Prenons par exemple ces tables:
    PROJECT:
    project_id project_name
    PRJ00001 .....
    PRJ00002 .....

    PROJECTMEMBERS:
    project_id user
    PRJ00001 Jean
    PRJ00001 Alexandre
    PRJ00002 Albert
    PRJ00002 Wilfried
    PRJ00002 Dominique
    J'ai besoin d'une requête qui me fournisse une ligne par projet, en concaténant les utilisateurs d'un même projet. Je veux donc comme résultat:

    project_id users
    "PRJ00001" "Jean, Alexandre"
    "PRJ00002" "Albert, Wilfried, Dominique"
    Après avoir recherché je suis tombé sur ce sujet qui semble apporter la réponse, pour MSSQL :
    http://www.developpez.net/forums/d97...-sous-requete/

    Hélas, je ne réussis pas à l'adapter à MySql.

    Voici mes essais :
    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
    DROP FUNCTION IF EXISTS MyConcat ;
    delimiter //
    CREATE FUNCTION MyConcat(projid varchar(50)) 
    RETURNS varchar(500)
    BEGIN 
        DECLARE TexteConcat varchar(500); 
        SET TexteConcat = '';  
     
        SELECT TexteConcat = TexteConcat + user_id + ' ' 
        FROM new_schema.project_members
        WHERE project_id = projid;
     
        RETURN TexteConcat;
    END 
    //
    delimiter ;
    qui me retourne un
    Error Code: 1415
    Not allowed to return a result set from a function

    Alors soit je cherche encore et j'essaie d'ajouter un "INTO"
    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
    DROP FUNCTION IF EXISTS MyConcat ;
    delimiter //
    CREATE FUNCTION MyConcat(projid varchar(50)) 
    RETURNS varchar(500)
    BEGIN 
        DECLARE TexteConcat varchar(500); 
        SET TexteConcat = '';  
     
        SELECT TexteConcat = TexteConcat + user_id + ' ' INTO TexteConcat
        FROM new_schema.project_members
        WHERE project_id = projid;
     
        RETURN TexteConcat;
    END 
    //
    delimiter ;
     
    SELECT project_id, MyConcat(project_id) FROM new_schema.projects;
    Création de la procédure OK, mais à l'appel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT project_id, MyConcat(project_id) FROM new_schema.projects;
    Error Code: 1172
    Result consisted of more than one row

    Alors depuis que je cherche il est temps de demander de l'aide...

    - "A l'aide ?"

    PS: j'ai aussi essayé d'envoyer "INTO" vers une variable qui n'est pas dans la boucle...
    PS2: MySQL version 5.1

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Ce que tu cherches à faire est de la cosmétique et n'est pas le boulot du SGBD mais celui du programme utilisateur.
    Cependant, avec MySQL, tu peux utiliser la fonction GROUP_CONCAT.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  3. #3
    Membre à l'essai
    Inscrit en
    Août 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    C'est excellent, je te remercie.

    J'ai bien compris la distinction en requête et cosmétique. Je m'appuie sur SQL pour alléger mon code, justement. S'il s'agissait d'une utilisation régulière, je ferai dans les normes. Là, ce sera du "one-shot".

    Et la fonction GROUP_CONCAT semble répondre à mon besoin. Nul besoin de fonction, il me suffit d'appeler :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT p.project_id,
           GROUP_CONCAT(m.user_id SEPARATOR ", ") 
    FROM new_schema.projects as p
    LEFT JOIN  new_schema.project_members as m
        ON  m.project_id = p.project_id;

  4. #4
    Membre à l'essai
    Inscrit en
    Août 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    Ceci dit, quelques précisions pour peuvent être utile à tout lecture ultérieur :

    Mon but principal était de ne pas faire "d'aller-retours" client-serveurs avec un joli foreach au milieu.

    En conservant cette optique, et en regardant mieux l'article que tu as mis en lien, voici la solution qui serait la plus adaptée dans le genre "chacun son boulot".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT DISTINCT p.project_id,
          m.user_id
    FROM new_schema.projects AS p
    LEFT JOIN  new_schema.project_members AS m
        ON  m.project_id = p.project_id
    ORDER BY p.project_id;
    Je récupère donc, bien ordonné et unitaires et donc aisément déchiffrable :
    PRJ00001 Jean
    PRJ00001 Alexandre
    PRJ00002 Albert
    PRJ00002 Wilfried
    PRJ00002 Dominique
    Sur lequel je fais (dans mon programme) une boucle, qui détecte la correspondance des "project_id" --> pas de stockage en mémoire mais traitement efficace. Je vais donc faire des tests de temps de réponse pour voir si je déporte cette partie dans mon code (mais ça en supprimerait la configurabilité "une requête" --> "un fichier résultat")

    NOTE: mon exemple trouve ici ses limites, puisqu'on obtient la base initiale. Il faut ajouter à cela les nombreuses informations qui viennent de "PROJECTS" (nom, description, identifiant, dates) et la grosse quantité de données dans le désordre de la base PROJECT_MEMBERS, en plus de données orphelines que je ne veux pas.

    Exemple de pseudo-code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    STRING latest_project_id = "";
    BOOLEAN first = TRUE;
    FOR EACH row IN resultat_requete_slq
      STRING project_id = row("project_id")
      IF project_id != latest_project_id
          PRINT NEWLINE
          PRINT project_id + " : "
          latest_project_id = project_id
      ENDIF
      IF first = TRUE THEN PRINT ", "
      PRINT row("user_id")
      first = FALSE
    NEXT

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

Discussions similaires

  1. Concaténer les différentes valeurs d'une colonne
    Par Kitty11 dans le forum Développement de jobs
    Réponses: 2
    Dernier message: 20/08/2013, 11h58
  2. Réponses: 16
    Dernier message: 12/12/2011, 12h17
  3. Mettre plusieurs valeurs d'une colonne dans un champ
    Par ljleyoshi dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 16/09/2011, 03h16
  4. Insérer plusieurs valeurs dans une colonne
    Par hadjiphp dans le forum Langage
    Réponses: 2
    Dernier message: 11/05/2009, 03h14
  5. concaténer plusieurs enregistrements sur une colonne
    Par pierre22 dans le forum Requêtes et SQL.
    Réponses: 12
    Dernier message: 10/09/2007, 19h26

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