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 != résultats en une colonne


Sujet :

Langage SQL

  1. #1
    Membre éclairé
    Inscrit en
    Mai 2003
    Messages
    271
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2003
    Messages : 271
    Points : 720
    Points
    720
    Par défaut Concatener != résultats en une colonne
    Bonjour,

    ma requête est sans doute assez classique, mais malgré les qques lectures sur le forum et ds les tutoriels, j'ai du mal à retrouver ce que je cherche.

    Je travaille sur une DB qui traite des informations des images (pour être précis, il s'agit de la DB du projet de gallerie web piwigo)
    La base contient notamment 3 tables:
    - image avec des propriétés de base de l image
    - tags avec id, name
    - et une table de liaison tags_image qui permet d'affecter plusieurs tags à une image.

    Je cherche à exporter toutes les propriétés par image.
    J'ai commencé par des outer join:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT img.id, img.name, img.comment, img.author, img.path, tags.name
    		FROM `phpwebgallery_images` as img
    		LEFT OUTER JOIN `phpwebgallery_image_tag` as img_tag ON img_tag.image_id = img.id
    		LEFT OUTER JOIN `phpwebgallery_tags` as tags ON tags.id = img_tag.tag_id
    		WHERE ( LENGTH(img.name) > 0 OR LENGTH(img.comment) > 0 OR LENGTH(tags.name) > 0 )
    Mais cela ne rempli pas mes besoins: j'aimerais retourner toutes les propriétés des images et tous les tags par image en 1 ligne par image; le tableau retourné doit être avec une colonne par propriété de base, plus 1 seule colonne tag contenant la concaténation des différents tags de l'image, séparés par une virgule.

    Comment faire cela?

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Points : 965
    Points
    965
    Par défaut
    Bonjour,

    Si vous utilisez MySQL comme le laisse supposer votre requête, regardez du coté de GROUP_CONCAT.

  3. #3
    Membre éclairé
    Inscrit en
    Mai 2003
    Messages
    271
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2003
    Messages : 271
    Points : 720
    Points
    720
    Par défaut
    y a t il qqch de spécifique à mysql ds ma requète?
    Merci pour la rapidité de la réponse, je ne connaissais pas cette commande.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT img.id, img.name, img.comment, img.author, img.path, GROUP_CONCAT(tags.name)
    		FROM `phpwebgallery_images` as img
    		LEFT OUTER JOIN `phpwebgallery_image_tag` as img_tag ON img_tag.image_id = img.id
    		LEFT OUTER JOIN `phpwebgallery_tags` as tags ON tags.id = img_tag.tag_id
    		WHERE ( LENGTH(img.name) > 0 OR LENGTH(img.comment) > 0 OR LENGTH(tags.name) > 0 ) GROUP BY img.id
    renvoie ce que je demandais.

    Pour la forme, y a t il une manière + standard d'écrire cette requète?
    Et pour mysql, celle ci est elle optimale?

  4. #4
    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
    Citation Envoyé par Eric80 Voir le message
    y a t il qqch de spécifique à mysql ds ma requète ?
    Les ` inutiles autour des noms de tables.

    Citation Envoyé par Eric80 Voir le message
    Pour la forme, y a t il une manière + standard d'écrire cette requète?
    Et pour mysql, celle ci est elle optimale?
    Je ne crois pas qu'il y ait un opérateur normatif de "string aggregation".

    Les jointures sont bien écrites mais il manque des informations dans votre GROUP BY. MySQL le permet mais c'est une source d'erreur potentielle.
    Prenez l'habitude de mettre dans votre GROUP BY toutes les colonnes de votre select hors aggrégat.

    Dans votre WHERE vous avez ce prédicat : LENGTH(tags.name) > 0
    Comme vous avez fait une jointure externe, vous risquez de faire disparaître le côté externe en plaçant ce prédicat dans le where.
    Il faudrait probablement le mettre en jointure.

    Au final j'écrirai votre requête de la façon 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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    SELECT
        img.id,
        img.name,
        img.comment,
        img.author,
        img.path,
        GROUP_CONCAT(tags.name)
    FROM
        phpwebgallery_images AS img
        LEFT OUTER JOIN phpwebgallery_image_tag AS img_tag
          ON img_tag.image_id = img.id
        LEFT OUTER JOIN phpwebgallery_tags AS tags
          ON tags.id = img_tag.tag_id
         AND ( LENGTH(img.name)    > 0
            OR LENGTH(img.comment) > 0
            OR LENGTH(tags.name)   > 0 )
    GROUP BY
        img.id,
        img.name,
        img.comment,
        img.author,
        img.path
    ORDER BY
        img.id ASC

  5. #5
    Membre éclairé
    Inscrit en
    Mai 2003
    Messages
    271
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2003
    Messages : 271
    Points : 720
    Points
    720
    Par défaut
    merci pour les tips, ce caractère initule est généré par phpmyadmin que j utilise pour tester.
    Le AND ds le OUTER JOIN semble inactif, en tous cas, mysql ne me renvoie pas le même tableau qu'avec ma requète ci dessus.
    Avec la dernière requète, meme les images ayant les 3 champs vide sont renvoyés.
    Je crois que je vais en rester au WHERE, avec le complément sur le group by.

  6. #6
    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
    Dans ce cas j'imagine que vous n'avez pas besoin des jointures externes :
    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
    SELECT
        img.id,
        img.name,
        img.comment,
        img.author,
        img.path,
        GROUP_CONCAT(tags.name)
    FROM
        phpwebgallery_images AS img
        INNER JOIN phpwebgallery_image_tag AS img_tag
          ON img_tag.image_id = img.id
        INNER JOIN phpwebgallery_tags AS tags
          ON tags.id = img_tag.tag_id
    WHERE
        LENGTH(img.name)    > 0
     OR LENGTH(img.comment) > 0
     OR LENGTH(tags.name)   > 0
    GROUP BY
        img.id,
        img.name,
        img.comment,
        img.author,
        img.path
    ORDER BY
        img.id ASC

  7. #7
    Membre éclairé
    Inscrit en
    Mai 2003
    Messages
    271
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2003
    Messages : 271
    Points : 720
    Points
    720
    Par défaut
    si, car les clause du where ne s'appliquent pas sur les memes critères que les join.
    J'avais commencé d'ailleurs par des inner join avant de réaliser que c'est bien des left outer join que je veux.
    Je veux recevoir les images ayant soit un commentaire, soit un nom, soit un ou plusieurs tags, ou évidemment une combinaison de ces propriétés.
    Si j'utilise des inner join, seuls celles avec des tags sont retournées...

    Le but de cette requète est ensuite de générer un script batch qui va tagger les propriétés qui vont bien dans les metadata IPTC de l'image. Suivant les cas, je tagge donc soit le nom (object name), soit le commentaire (caption), soit les tags (keywords), soit l'auteur (writer), ce qui me fait penser que j'ai oublié ce dernier critère ds mon where...

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

Discussions similaires

  1. [XL-2003] Création d'onglets en fonction du résultat d'une colonne
    Par BAYRAL dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 15/02/2011, 16h37
  2. Réponses: 5
    Dernier message: 10/02/2011, 09h55
  3. [Oracle] Ressource id#3 comme résultat d'une colonne
    Par dspade dans le forum PHP & Base de données
    Réponses: 0
    Dernier message: 21/01/2010, 17h27
  4. [dlmread] Résultat avec une colonne de 0 en plus
    Par pelotudo dans le forum MATLAB
    Réponses: 2
    Dernier message: 03/04/2008, 16h07

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