Précédent   Forum des professionnels en informatique > Bases de données > MySQL
MySQL Forum d'entraide MySQL. Avant de poster -> FAQ MySQL, Tutoriels MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 12/09/2011, 15h36   #1
Nouveau Membre du Club
 
Inscription : juillet 2007
Messages : 117
Détails du profil
Informations forums :
Inscription : juillet 2007
Messages : 117
Points : 25
Points : 25
Par défaut Récupérer une liste via une table de liaison

Bonjour,

Tout d'abord voici le schéma de ma base, j'ai 3 trois tables, dont une fait office de table de liaison:

table "article":

idArticle
title
content

table "categorie"

idCatgorie
name

table article_categorie:

fk_idArticle
fk_idCategorie

Cette table de liaison me permet d'assigner plusieurs catégories pour un article.

Pour récupérer mes articles, je fais un simple SELECT :

Code :
SELECT idArticle, title, content FROM article...
Cela me retourne la liste de mes articles, normal quoi.

Mais maintenant, j'aimerais que ça me retourne la liste des articles, avec pour chaque article la liste des catégories assignées à cet article...

Et là je ne sais pas comment faire...

Une idée pour de l'aide?

Merci d'avance
nesswaw est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/09/2011, 15h40   #2
Membre Expert
 
Avatar de Yanika_bzh
 
Homme Yannick
Ingénieur Etudes & Developpements
Inscription : février 2006
Messages : 1 125
Détails du profil
Informations personnelles :
Nom : Homme Yannick
Localisation : France, Deux Sèvres (Poitou Charente)

Informations professionnelles :
Activité : Ingénieur Etudes & Developpements
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2006
Messages : 1 125
Points : 1 670
Points : 1 670
Documentez vous sur les jointures (internes dans votre cas), elles feront votre bonheur

Bon courage
__________________
Dans la connaissance du monde, ceux qui ne savent rien en savent toujours autant que ceux qui n'en savent pas plus qu'eux. (Pierre Dac)
Yanika_bzh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/09/2011, 16h00   #3
Nouveau Membre du Club
 
Inscription : juillet 2007
Messages : 117
Détails du profil
Informations forums :
Inscription : juillet 2007
Messages : 117
Points : 25
Points : 25
Bonjour,

Merci pour votre réponse, j'ai essayer cela:

Code :
1
2
3
4
 
SELECT * FROM article a
INNER JOIN article_categorie ac ON a.idArticle = ac.fk_idArticle
INNER JOIN categorie c ON ac.fk_idCaegorie = c.idCategorie
Si j'ai 1 article qui est lié avec 3 catégories, ça me retourne 3 lignes, ce qui est normal, si je veux une seule ligne je dois traiter ça avec un autre language (php dans mon cas).

Du coup je me pose une nouvelle question: Est-ce qu'il est possible que ça me retourne 1 ligne par article, avec 1 champ en plus "listCategorie" qui contient un genre de CONCAT() sur les catégories de mon article courant?

Merci
nesswaw est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/09/2011, 16h16   #4
Membre Expert
 
Avatar de Yanika_bzh
 
Homme Yannick
Ingénieur Etudes & Developpements
Inscription : février 2006
Messages : 1 125
Détails du profil
Informations personnelles :
Nom : Homme Yannick
Localisation : France, Deux Sèvres (Poitou Charente)

Informations professionnelles :
Activité : Ingénieur Etudes & Developpements
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2006
Messages : 1 125
Points : 1 670
Points : 1 670
peut etre ici ?

Bon courage
__________________
Dans la connaissance du monde, ceux qui ne savent rien en savent toujours autant que ceux qui n'en savent pas plus qu'eux. (Pierre Dac)
Yanika_bzh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/09/2011, 17h31   #5
Nouveau Membre du Club
 
Inscription : juillet 2007
Messages : 117
Détails du profil
Informations forums :
Inscription : juillet 2007
Messages : 117
Points : 25
Points : 25
Yeah! Merci, voici mon résultat:

Code :
1
2
3
4
 
SELECT *, GROUP_CONCAT(c.name ORDER BY c.name SEPARATOR ', ') AS listeCat FROM article a
INNER JOIN article_categorie ac ON a.idArticle = ac.fk_idArticle
INNER JOIN categorie c ON ac.fk_idCaegorie = c.idCategorie
Une autre question: Que je mette INNER JOIN OU LEFT JOIN, ça me donne le même résultat, donc quelle est la différence entre les deux? un est plus rapide que l'autre?

PS: Il y a une erreur dans la FAQ, les deux derniers paramètres de la fonction GROUP_CONCAT() sont inversés.

Merci pour l'aide.
nesswaw est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/09/2011, 23h57   #6
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 029
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
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 : 11 029
Points : 18 327
Points : 18 327
Envoyer un message via MSN à CinePhil
INNER JOIN ne donne que les lignes qui ont une correspondance dans les deux tables

Exemple :
Table A :
id, txt
1, 'toto'
2, 'titi'
3, 'tata'
4, 'tutu'

Table B :
id, idA
1, 2
2, 3
3, 2

Code :
1
2
3
4
SELECT A.id AS idA, A.txt, B.id AS idB
FROM A
INNER JOIN B ON A.id = B.idA
ORDER BY A.id
Résultat :
idA, txt, idB
1, 'toto', 3
2, 'titi', 1
3, 'tata', 2
=> 'tutu' n'a pas de correspondance dans la table B et n'est pas retourné par la requête.

LEFT JOIN donne toutes lignes de la table de gauche et la correspondance de données quand il y en a dans la table de droite, NULL quand il n'y en a pas.
Code :
1
2
3
SELECT B.id AS idB, A.txt
FROM A
LEFT JOIN B ON A.id = B.idA
Résultat :
idA, txt, idB
1, 'toto', 3
2, 'titi', 1
3, 'tata', 2
4, 'tutu', NULL
=> 'tutu' n'a pas de correspondance dans la table B mais est retourné par la requête avec NULL dans la colonne issue de B.
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« 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 Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/09/2011, 13h31   #7
Nouveau Membre du Club
 
Inscription : juillet 2007
Messages : 117
Détails du profil
Informations forums :
Inscription : juillet 2007
Messages : 117
Points : 25
Points : 25
Merci pour vos informations

Après avoir fait deux-trois test, un nouveau problème survient...si je prends ma requête et que je rajoute un WHERE:

Code :
1
2
3
4
5
 
SELECT *, GROUP_CONCAT(c.name ORDER BY c.name SEPARATOR ', ') AS listeCat FROM article a
INNER JOIN article_categorie ac ON a.idArticle = ac.fk_idArticle
INNER JOIN categorie c ON ac.fk_idCaegorie = c.idCategorie
WHERE c.idCategorie=1
Mon GROUP_CONCAT me retourne que la catégorie courante, ce qui est normal à cause de mon WHERE...mais j'aimerais qu'il me renvoie toujours toutes les catégories de mon article même quand j'ai un WHERE...

Est-ce possible toujours en une requête? ou une sous-requête?

Merci
nesswaw est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/09/2011, 13h33   #8
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 029
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
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 : 11 029
Points : 18 327
Points : 18 327
Envoyer un message via MSN à CinePhil
Citation:
Envoyé par nesswaw Voir le message
Mon GROUP_CONCAT me retourne que la catégorie courante, ce qui est normal à cause de mon WHERE...mais j'aimerais qu'il me renvoie toujours toutes les catégories de mon article même quand j'ai un WHERE...
Euh... là il va falloir que tu nous expliques plus concrètement ton besoin car c'est ou bien pour une catégorie ou bien pour plusieurs !
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« 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 Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/09/2011, 13h55   #9
Nouveau Membre du Club
 
Inscription : juillet 2007
Messages : 117
Détails du profil
Informations forums :
Inscription : juillet 2007
Messages : 117
Points : 25
Points : 25
J'explique:

J'ai une table qui contient des articles.
J'ai une table qui contient une liste de catégories.
J'ai une table de liaison, parce un article peut avoir plusieurs catégories.

J'aimerais afficher une liste d'articles sous forme de liste tabulaire avec l'id de l'article, son titre, et les catégories de l'article:

id article | titre article | catégories
---------- | ------------ | ------------
1 | Titre 1 | Cat1, Cat2
2 | Titre 2 | Cat1, Cat3
3 | Titre 3 | Cat2

Mais j'aimerais aussi afficher cette liste suivant divers filtres, comme par exemple afficher tous les articles de la "Cat2", ce qui me donnerait ce résultat :

id article | titre article | catégories
---------- | ------------ | ------------
1 | Titre 1 | Cat1, Cat2
3 | Titre 3 | Cat2

Vous voyez le truc?

Merci
nesswaw est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/09/2011, 14h16   #10
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 029
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
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 : 11 029
Points : 18 327
Points : 18 327
Envoyer un message via MSN à CinePhil
Autrement dit, tu voudrais afficher tous les articles de la catégorie 2 et toutes les catégories de ces articles ?

GROUP_CONCAT s'utilise avec GROUP BY !
Évite la guerre des étoiles !

Il te faut une autre jointure sur la table associative pour récupérer toutes les catégories des articles de la catégorie 2.

1) Quelles sont les articles de la catégorie 2 ?
Code :
1
2
3
4
SELECT a.idArticle
FROM article a
INNER JOIN article_categorie ac ON a.idArticle = ac.fk_idArticle
WHERE ac.fk_idCategorie = 2
2) Quelles sont toutes les catégories de ces articles ?
Code :
1
2
3
4
5
6
7
8
SELECT a.idArticle, a.titreArticle,
    GROUP_CONCAT(c.name ORDER BY c.name SEPARATOR ', ') AS listeCat 
FROM article a
INNER JOIN article_categorie ac ON a.idArticle = ac.fk_idArticle
    LEFT OUTER JOIN article_categorie ac1 ON ac1.fk_idArticle = ac.fk_idArticle
        LEFT OUTER JOIN categorie c ON ac1.fk_idCaegorie = c.idCategorie
WHERE ac.fk_idCategorie = 2
GROUP BY a.idArticle, a.titreArticle
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« 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 Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/09/2011, 15h14   #11
Nouveau Membre du Club
 
Inscription : juillet 2007
Messages : 117
Détails du profil
Informations forums :
Inscription : juillet 2007
Messages : 117
Points : 25
Points : 25
Citation:
Envoyé par CinePhil Voir le message
Autrement dit, tu voudrais afficher tous les articles de la catégorie 2 et toutes les catégories de ces articles ?
Afficher tous les articles de la catégorie 2 et pour chaque article afficher les catégories qui lui sont assignées.

Citation:
Envoyé par CinePhil Voir le message
GROUP_CONCAT s'utilise avec GROUP BY !
Évite la guerre des étoiles !
??

Citation:
Envoyé par CinePhil Voir le message
Il te faut une autre jointure sur la table associative pour récupérer toutes les catégories des articles de la catégorie 2.

1) Quelles sont les articles de la catégorie 2 ?
Code :
1
2
3
4
SELECT a.idArticle
FROM article a
INNER JOIN article_categorie ac ON a.idArticle = ac.fk_idArticle
WHERE ac.fk_idCategorie = 2
2) Quelles sont toutes les catégories de ces articles ?
Code :
1
2
3
4
5
6
7
8
SELECT a.idArticle, a.titreArticle,
    GROUP_CONCAT(c.name ORDER BY c.name SEPARATOR ', ') AS listeCat 
FROM article a
INNER JOIN article_categorie ac ON a.idArticle = ac.fk_idArticle
    LEFT OUTER JOIN article_categorie ac1 ON ac1.fk_idArticle = ac.fk_idArticle
        LEFT OUTER JOIN categorie c ON ac1.fk_idCaegorie = c.idCategorie
WHERE ac.fk_idCategorie = 2
GROUP BY a.idArticle, a.titreArticle
Avec la 2ème requête ça a l'air de fonctionner, par contre si j'enlève le WHERE, il m'affiche les catégories en double pour chaque article, c'est normal ?


Ça devient assez complexe, là. Je m'y perds un peu.

Merci pour l'aide
nesswaw est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/09/2011, 16h06   #12
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 029
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
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 : 11 029
Points : 18 327
Points : 18 327
Envoyer un message via MSN à CinePhil
Citation:
Envoyé par CinéPhil
GROUP_CONCAT s'utilise avec GROUP BY !
Voir la doc MySQL !

Citation:
Envoyé par CinéPhil
Évite la guerre des étoiles !
J'avais un lien vers un article qui explique qu'il ne faut pas utiliser SELECT * mais nommer les colonnes dont on a besoin dans le SELECT mais le lien est mort.

Citation:
Envoyé par nesswaw
Avec la 2ème requête ça a l'air de fonctionner, par contre si j'enlève le WHERE, il m'affiche les catégories en double pour chaque article, c'est normal ?
J'avais essayé de te montrer la construction progressive de la requête mais apparemment tu n'as pas compris !

La requête à utiliser est évidemment la seconde, la première n'étant qu'une étape intermédiaire et elle est incluse dans la seconde.
À la première requête, j'ai ajouté une jointure vers la table associative pour récupérer toutes les catégories des articles de la catégorie 2.

Si tu enlèves le WHERE, bien entendu, tu te retrouves avec tous les articles de toutes les catégories et comme il y a double jointure sur la table associative, tu as les résultats en double !
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« 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 Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 23h58.


 
 
 
 
Partenaires

Hébergement Web