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

Langage SQL Discussion :

Concatener un resultat


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Inscrit en
    Mars 2007
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 22
    Points : 11
    Points
    11
    Par défaut Concatener un resultat
    Bonjour a tous, j'ai un probleme pour recuperer un resultat. Pour vous l'expliquer voici un exemple :
    J'ai 3 voitures, et ces voitures peuvent avoir une, deux ou trois couleurs (pas plus)

    table voiture

    voit_id = 1 / voit_nom = clio
    voit_id = 2 / voit_nom = 206
    voit_id = 3 / voit_nom = 4L

    table couleur_voiture

    coul_id = 1 / voit_id = 1 / coul = 1 / motif = bleue

    coul_id = 2 / voit_id = 2 / coul = 1 / motif = rouge
    coul_id = 3 / voit_id = 2 / coul = 2 / motif = blanche

    coul_id = 4 / voit_id = 3 / coul = 1 / motif = jaune
    coul_id = 5 / voit_id = 3 / coul = 2 / motif =verte
    coul_id = 6 / voit_id = 3 / coul = 3 / motif = noire

    Et j'aimerai avoir en sortie :
    clio || bleue
    206 || rouge - blanche
    4L || jaune - verte - noire


    J'ai essayé avec concat, mais ma requete ne fonctionne que si la voiture est de 3 couleurs, sinon j'ai une ligne vide en retour :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select concat (a.motif,' - ',b.motif,' - ',c.motif) from
    (select motif from couleur where voit_id=3 and coul=1) a,
    (select motif from couleur where voit_id=3 and coul=2) b,
    (select motif from couleur where voit_id=3 and coul=3) c
    me donne bien jaune-verte-noire, mais si je met dans les Where 'voit_id=1' ca me renvoie une ligne vide.

    J'ai du coup essayé d'introduire des 'if' dans le select concat pour dire 'si le motif est null remplacer motif par 0' par exemple, mais ca marche pas mieux.

    Bon, je suis un peu une brele en SQL alors si qq un aurait une idée je suis preneur.

    Merci beaucoup,

    Mat.

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Celà s'appelle du STRING AGGREGATION, et les solutions varient en fonction du SGBD.

    Je vous invite à effectuer quelques recherches sur ce mot clef avec votre moteur favori.

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 781
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 781
    Points : 52 769
    Points
    52 769
    Billets dans le blog
    5
    Par défaut
    La notion de "STRING AGGREGATION" ne fait pas partie des fonctions de SQL, mais peut être réalisé par des requêtes récursives notamment.

    Dans votre cas, comme c'est limité à 3, c'est beaucoup plus simple, car vous n'êtes pas obligé d'utiliser une requête récursive :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CREATE TABLE voiture (voit_id int, voit_nom VARCHAR(16))
     
    INSERT INTO voiture VALUES (1, 'clio')
    INSERT INTO voiture VALUES (2, '206')
    INSERT INTO voiture VALUES (3, '4L')
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TABLE couleur (coul_id int, motif varchar(16))
     
    INSERT INTO couleur VALUES (1, 'bleu')
    INSERT INTO couleur VALUES (2, 'rouge')
    INSERT INTO couleur VALUES (3, 'blanche')
    INSERT INTO couleur VALUES (4, 'jaune')
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE couleur_voiture (voit_id int, coul_id int)
     
    INSERT INTO couleur_voiture VALUES (1, 1)
    INSERT INTO couleur_voiture VALUES (2, 2)
    INSERT INTO couleur_voiture VALUES (2, 4)
    INSERT INTO couleur_voiture VALUES (3, 1)
    INSERT INTO couleur_voiture VALUES (3, 3)
    INSERT INTO couleur_voiture VALUES (3, 4)
    La solution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    WITH T AS
    (SELECT voit_id, CV.coul_id, motif, ROW_NUMBER() OVER(PARTITION BY voit_id ORDER BY CV.coul_id) AS N
     FROM   couleur_voiture AS CV
            INNER JOIN couleur AS C
                  ON CV.coul_id = C.coul_id)
    SELECT V.*, COALESCE(T1.motif, '') + COALESCE(' - ' + T2.motif, '')  + COALESCE(' - ' + T3.motif, '') AS voit_couleur
    FROM   voiture AS V
           LEFT OUTER JOIN T AS T1
                ON V.voit_id = T1.voit_id AND T1.N = 1          
           LEFT OUTER JOIN T AS T2
                ON V.voit_id = T2.voit_id AND T2.N = 2            
           LEFT OUTER JOIN T AS T3
                ON V.voit_id = T3.voit_id AND T3.N = 3
    Résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    voit_id     voit_nom              voit_couleurs
    ----------- ---------------- ------------------------------------------------------
    1           clio             bleu
    2           206              rouge - jaune
    3           4L               bleu - blanche - jaune
    Cette requête utilise une CTE comme je l'ai décrit ici : http://sqlpro.developpez.com/cours/s...te-recursives/

    Il est bien entendu possible de ne pas utiliser de CTE, comme il est possible, si votre SGBDR ne supporte pas les fonctions de fenêtrage (ROW_NUMBER), de s'en passer.

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  4. #4
    Membre à l'essai
    Inscrit en
    Mars 2007
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 22
    Points : 11
    Points
    11
    Par défaut
    Excellent!!!
    Je vais me mettre la dessus pour bien comprendre et pouvoir l'adapter a mon besoin.
    Merci beaucoup a vous deux,

    Mat.

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

Discussions similaires

  1. Concatener les resultats d'un subquery
    Par renotm dans le forum SQL
    Réponses: 3
    Dernier message: 23/02/2007, 15h43
  2. Concatenation des resultat d'une requete SQL
    Par zian974 dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 05/09/2006, 13h56
  3. [SQL] Concatenation des resultat d'une requete SQL
    Par zian974 dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 05/09/2006, 13h11
  4. [requete] Concatenation du resultat de la requete
    Par Sherkhan dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 06/02/2006, 10h19
  5. [requete] Concatenation du resultat
    Par Sherkhan dans le forum Langage SQL
    Réponses: 2
    Dernier message: 04/02/2006, 07h51

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