Partage
  • Partager sur Facebook
  • Partager sur Twitter

Jointure sur 3 tables avec n conditions

    8 janvier 2020 à 0:04:09

    Bonjour,

    J'ai cherché dans différents cours et sur Google mais je n'ai pas trouvé de réponse à ma question donc je viens solliciter vos lumières :)

    Mon problème est le suivant : j'ai trois tables :

    - table fichier avec un id, un titre, etc.

    - table tag avec un id, un intitulé, etc.

    - un table d'association lien : un id (mais après tout ce champ n'est peut-être pas utile ?), un champ fichier (qui correspond à l'id de ma table fichier) et un champ tag (qui correspond à l'id de ma table tag).

    Un fichier peut avoir plusieurs tags, et évidemment chaque tag peut être appliqué à plusieurs fichiers.

    J'essaie de faire une requête SQL pour trouver tous les fichiers qui ont le tag d'id = x1 et le tag d'id = x2... et le tag d'id = xn (sans avoir de redondance dans ma liste de résultats). La deuxième étape sera d'ajouter une condition SAUF le tag y1 et le tag yn ... et le tag ym, mais ce sera pour après !

    J'avais écrit ça mais ça ne fonctionne pas (ici je fais un test avec 3 tags dont les id sont 1, 3 et 7) ; je comprends pourquoi mais je vois pas comment résoudre mon problème :

    SELECT f.id as id_fichier, t.id as id_tag, t.titre as titre_tag FROM lien l, fichier f, tag t WHERE l.fichier = f.id AND l.tag = t.id AND t.id IN(1,3,7)



    L'idée est que j'ai une liste des n id des tags dans un array (j'utilise PHP).

    Je vous remercie par avance pour votre aide !

    -
    Edité par PaulBlanc5 8 janvier 2020 à 0:17:23

    • Partager sur Facebook
    • Partager sur Twitter
      8 janvier 2020 à 9:57:12

      Bonjour,

      PaulBlanc5 a écrit:

      table d'association lien : un id (mais après tout ce champ n'est peut-être pas utile ?)

      C'est juste, une table de relation ne représente pas une entité, elle n'a pas besoin d'id mais d'une clé primaire composée et de deux clés étrangères. Ton modèle serait donc :

      • fichier ( id [pk], chemin, etc. )
      • tag ( id [pk], libelle, etc. )
      • fichier_tag ( id_fichier [pk][fk], id_tag [pk][fk] )

      PaulBlanc5 a écrit:

      trouver tous les fichiers qui ont le tag d'id = x1 et le tag d'id = x2... et le tag d'id = xn

      Cela s'appelle une intersection. La plupart des SGBDR (mais pas MySQL) propose le mot clé INTERSECT, avec quel SGBD fonctionnes-tu ?

      PaulBlanc5 a écrit:

      J'avais écrit ça mais ça ne fonctionne pas

      Oui car ta condition avec IN correspond à un OU, et ce n'est pas un OU dont tu as besoin ... mais d'une intersection ...

      -
      Edité par Benzouye 8 janvier 2020 à 9:58:44

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        8 janvier 2020 à 16:46:58

        Merci pour ton retour !

        J'utilise effectivement MySQL... existe-t-il une astuce ou bien dois-je me tourner vers un autre SGBD ?

        Et avec Intersect du coup, il faudrait que je fasse (n-1) INTERSECT ? Pourrais tu me donner un exemple ?

        • Partager sur Facebook
        • Partager sur Twitter
          8 janvier 2020 à 17:01:43

          Avec MySQL, une astuce est de multiplier des jointures internes pour chaque critère, exemple :

          Les fichiers (distincts) liés aux tags 1, 2 et 3

          SELECT DISTINCT F.id
          FROM
          	fichier F
          		INNER JOIN lien L1
          			ON F.id = L1.fichier
          			AND L1.tag = 1
          		INNER JOIN lien L2
          			ON L1.fichier = L2.fichier
          			AND L2.tag = 2
          		INNER JOIN lien L3
          			ON L2.fichier = L3.fichier
          			AND L3.tag = 3

          -
          Edité par Benzouye 8 janvier 2020 à 17:02:30

          • Partager sur Facebook
          • Partager sur Twitter
          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL

          Jointure sur 3 tables avec n conditions

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown