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 :

Comment différencier les tables "jointurées" ?


Sujet :

Langage SQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Janvier 2024
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Janvier 2024
    Messages : 113
    Par défaut Comment différencier les tables "jointurées" ?
    bonjour
    Je suis en train de tenter de faire un petit moteur de recherche pour mon site perso avec un formulaire qui lance un php qui lance des requêtes !
    La recherche se fait sur 2 tables une d'auteurs et une de titres. Pour ça elles sont "jointurées" (je ne sais pas comment on dit que deux tables font l'objet d'une jointure ...)
    Sauf que je voudrais que le message ne soit pas le même selon la table d'où provient le résultat.
    Comment faire ? Je n'ai pas trouver d'exemple dans les tutos.

  2. #2
    Membre chevronné
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2022
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 21
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2022
    Messages : 373
    Par défaut
    Bjr,
    Pas le même message ???
    C'est un moteur de recherche ou un chatbox ? Soit plus clair stp,
    Tu veux savoir de quel table provient le résultat , mais pk ?
    Un problème sans solution est un problème mal posé. (Albert Einstein)

  3. #3
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 502
    Par défaut
    Citation Envoyé par noradan Voir le message
    Sauf que je voudrais que le message ne soit pas le même selon la table d'où provient le résultat.
    Comment faire ? Je n'ai pas trouver d'exemple dans les tutos.
    Est-ce que c'est une vraie jointure (avec une clause JOIN ou un produit cartésien FROM table1, table2), ce qui consiste formellement à les mettre côte à côte, donc avec des colonnes propres à chacune, ou s'agit-il d'une UNION qui, elle, consiste plutôt à les placer l'une après l'autre, donc avec des colonnes communes ?

    Si c'est une vraie jointure, il te suffit de choisir la bonne colonne. Si c'est une union, soit tu réécris ta requête au propre pour effectuer des jointures, soit tu intègres dans chaque SELECT un identifiant constant propre (par exemple un numéro comme 1 ou 2) qui te permettra d'identifier la source de chaque tuple et de les discriminer ensuite avec WHERE.

    Montre-nous ta requête, s'il-te-plaît.

  4. #4
    Membre averti
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Janvier 2024
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Janvier 2024
    Messages : 113
    Par défaut
    Heu...
    C'est une colle !
    Je n'avais pas pensé à ces distinctions.
    En fait j'ai une table avec des auteurs et une référence vers une page html contenant des infos sur l'auteur et une table avec des titres d'oeuvres et bien sûr une colonne avec les auteurs.
    Donc par exemple si on écrit en recherche "victor hugo" on doit avoir comme réponse aussi bien "Victor Hugo -- Auteur" qui sera un lien cliquable mais aussi
    "Les Misérables par Victor Hugo, Notre-Dame de Paris par Victor Hugo etc

    Déjà je ne sais pas très bien compte tenu de ce que tu as dit quel est le type de jonction le mieux adapté.
    J'ai l'impression que c'est une union...
    donc il suffirait que j'ajoute une colonne supplémentaire avec un identifiant (c'est l'idée bête je j'avais eu mais je me suis dit qu'il y avait peut-être plus intelligent).

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 502
    Par défaut
    Bonjour,

    Citation Envoyé par noradan Voir le message
    J'ai l'impression que c'est une union...
    Non, c'est bien une jointure. Et dans cette situation, ton résultat est bien une table de n lignes et m colonnes. Chaque ligne correspond à une possibilité de ta requête et donc, à chaque fois, cette ligne contient à la fois l'auteur et le nom de l'ouvrage.

    donc il suffirait que j'ajoute une colonne supplémentaire avec un identifiant (c'est l'idée bête je j'avais eu mais je me suis dit qu'il y avait peut-être plus intelligent).
    C'est effectivement comme ça que l'on fait et, mieux encore, on pose ensuite les contraintes d'intégrité en déclarant notamment la colonne « auteur » de la table des ouvrages, qui contient l'identifiant de l'auteur, comme « clé étrangère » référençant la clé primaire de la table des auteurs.

    Concrètement :

    Tu composes d'abord une table « auteurs » :
    id_auteur nom description
    1 Victor Hugo (1802 - 1885)
    2 Albert Camus (1913 - 1960)

    Tu composes ensuite une table « ouvrages » :
    id_ouvrage id_auteur titre url description
    1 1 Les misérables https://quelquepart.com/lesmiserables (…)
    2 1 Notre-Dame de Paris https://quelquepart.com/nddp.php
    3 2 L'étranger https://autrepart/letranger.html
    4 2 La peste https://ailleurs.com/lapeste.php
    5

    Dans cet exemple, on désigne la première colonne de chaque table comme clé primaire. Elle contiennent donc un identifiant unique pour chaque ligne qui, à lui seul, permet de retrouver et d'isoler avec certitude la ligne entière et son contenu. Cet identifiant peut prendre n'importe quelle forme tant que l'unicité est respectée mais le plus naturel consiste bien sûr à utiliser un numéro, lequel est en général automatiquement attribué et incrémenté par le SGBD si on a pris soin de lui demander de le faire à la création de la table.

    La deuxième colonne de la table « ouvrage » est une « clé étrangère ». Si tu la définis comme telle, tu indiques au serveur que :
    • Ce qu'elle contient est officiellement un des ID de la table « auteur » (donc que la ligne référence un auteur donné) ;
    • Qu'on ne peut y insérer que des valeurs qui existent déjà dans la première colonne de la table « auteur », faute de quoi l'insertion de la ligne entière doit échouer ;
    • Qu'on ne peut supprimer de « auteurs » une ligne qui est référencée par une ou plusieurs lignes de « ouvrages » (il faut d'abord faire le ménage dans « ouvrages » si on souhaite le faire).


    Les contraintes d'intégrités sont optionnelles mais fortement conseillées. Si tu ne l'as pas fait, cela ne t'empêchera cependant pas d'effectuer une requête quand même.

    Tu interroges ensuite ta base comme suit, en établissant une jointure entre tes deux tables :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT * 
      FROM ouvrages
     
      JOIN auteurs
     USING (id_auteur)
     
     WHERE nom = "Victor Hugo"

    Ce faisant, tu indiques ici que les deux tables doivent être associés en fonction d'un critère commun, ici le champ « id_auteur ». Comme tu peux très bien avoir m lignes correspondant à une valeur donnée dans une table et n lignes correspondant à la même valeur dans l'autre, la base effectue un produit cartésien, c'est-à-dire qu'elle va en gros composer toutes les combinaisons possibles, donc m×n combinaisons en tout. Mais comme ici (comme dans la plupart des cas), la colonne concernée est la clé primaire de l'une des tables (où chaque valeur est unique), tu obtiens 1×n combinaisons, c'est-à-dire le nombre de lignes correspondantes de l'autre table. Le WHERE s'applique ensuite comme filtre sur le résultat entier, en ne sélectionnant que les lignes qui t'intéressent, soit ici les lignes dont l'auteur est « Victor Hugo ».

    Tu obtiens alors :

    id_auteur nom description id_ouvrage id_auteur titre url description
    1 Victor Hugo (1802 - 1885) 1 1 Les misérables https://quelquepart.com/lesmiserables (…)
    1 Victor Hugo (1802 - 1885) 2 1 Notre-Dame de Paris https://quelquepart.com/nddp.php

    Au sein de cet ensemble complet, tu peux alors sélectionner les colonnes qui t'intéressent (d'où le nom).

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT nom, titre, url…

    nom titre url
    Victor Hugo Les misérables https://quelquepart.com/lesmiserables
    Victor Hugo Notre-Dame de Paris https://quelquepart.com/nddp.php

    … qui est bien un sous-ensemble du résultat ci-dessus.

    Voilà pour une jointure élémentaire. Tu auras très bien besoin des jointures ouvertes, mais chaque chose en son temps.

    Maintenant, qu'entendais-tu exactement par :

    Sauf que je voudrais que le message ne soit pas le même selon la table d'où provient le résultat.
    … ?

  6. #6
    Membre averti
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Janvier 2024
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Janvier 2024
    Messages : 113
    Par défaut
    Merci pour le cours privé sur les jointure !
    j'envisageais la chose de façon plus simple car je n'ai pas l'intention de récupérer des infos de la table auteur lors d'un succès dans la table ouvrage.
    Les deux tables seraient complètement indépendantes

    Une table "auteur" comme tu as fait
    id - nom - lien
    mais j'envisageais la table "ouvrage" plus simplement
    id - auteur - titre - lien

    où au lieu de faire référence au même identifiant pour les auteurs qu'à la table "auteur" ce qui en effet pour ce que j'ai compris nécessite une jointure
    j'écris le nom explicitement
    la requête se faisant d'abord sur les auteurs puis sur les ouvrages et (c'est là le coup du message) et renvoie
    Auteur VICTOR HUGO (1802-1885) lien_vers_une_page
    Ouvrage LES MISERABLES par Victor Hugo ( en gras par exemple) lien_vers_une_page
    etc

    Une requête sur "misérables" retournant uniquement
    Ouvrage LES MISERABLES par Victor Hugo lien_vers_une_page

    Comme je ne récupère rien de la première table lorsque je j'affiche un succès sur la deuxième je me dis que dans l'esprit c'est plutôt une union mais dans la pratique...
    Les tuto parlent toujours de jointure (ce qui en effet est plus sophistiqué).

    Du coup il y a un souci car je viens de lire des choses sur UNION or le succès sur la table "auteur" ne retourne pas le même nombre de colonne que sur la table ouvrage puisqu'un succès dans celle-ci retourne le nom de l'auteur en plus

    Pour en faire une il faudrait que j'ajoute une colonne vide à la table auteur portant le même nom que celle des auteurs dans la table "ouvrage" (j'espère que tu as compris LOL!)

    Evidemment il y a la solution idiote de faire deux requêtes sauf que je voudrais bénéficier du classement par pertinence sur les deux car dans mon cas concret (des groupes de musiciens (p.ex. Nirvana, Les Beatles, Indochine etc) et des titres d'albums) il pourrait y avoir un nom de groupe (souvent un seul mot ou deux) qui coïncide avec un titre d'album d'un autre parfois même du même groupe (c'est parfois le cas lors du premier album).

    Mon problème est-il plus claire ?

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 502
    Par défaut
    Il a fallu que je m'accroche un peu mais j'ai fini par comprendre ton angle de vision des choses : tu as deux tables a priori indépendantes (auteurs et ouvrages) même si l'on peut établir une relation entre les deux, ces deux tables exposent chacune un champ humainement lisible et ton interface propose un champ « universel » qui permet de faire une recherche sur tout ce qui contient du texte à travers la base. C'est effectivement à la mode et j'en ai moi-même écrit une, qui restreint le contenu d'une liste initialement complète au fur et à mesure que l'on tape.

    En ce sens, ce serait effectivement une UNION, mais ce n'est pas forcément la meilleure approche à suivre.

    On rappelle déjà que les unions en SQL sont en fait un des opérateurs ensemblistes UNION, INTERSECT et EXCEPT. Lorsque tu associes deux sous-ensembles (les tables) en un seul, les éléments (les lignes, ou tuples) doivent tous être de même type, ou à tout le moins compatibles : même nombre de colonnes, dans le même ordre et donc les types doivent être respectivement compatibles (texte avec texte, nombre avec nombre…), justement pour pouvoir être rassemblés au sein d'une même table.

    Pour en faire une il faudrait que j'ajoute une colonne vide à la table auteur portant le même nom que celle des auteurs dans la table "ouvrage" (j'espère que tu as compris LOL!)
    Pas dans la table elle-même, mais dans la requête, c'est tout-à-fait envisageable. Tu peux également introduire un champ constant dans chacune des tables qui permette justement d'en distinguer la source. Tu peux écrire par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT 'auteurs' as source, id, nom as libelle, null as url
      FROM auteurs
     WHERE nom LIKE '%Victor Hugo%'
     
     UNION
     
    SELECT 'ouvrages' as source, id, titre as libelle, url
      FROM ouvrages
     WHERE titre LIKE '%Victor Hugo%'
    Tu obtiendrais alors :

    source id libelle url
    auteurs 1 Victor Hugo null
    ouvrages 1 Les misérables, par Victor Hugo http://quelquepart.com/lmis.html
    ouvrages 2 Notre-Dame de Paris, par Victor Hugo http://quelquepart.com/nddp.html

    … par contre, cela n'est intéressant que si tu agrèges des extraits qui proviennent déjà de la même table ou, au contraire, si tu veux rassembler des éléments provenant de sources qui n'ont rien à voir entre elles mais dont lesdits éléments ont des traits communs sur la forme.

    En revanche, s'il existe une table « auteurs », aller écrire explicitement Victor Hugo en toutes lettres dans un champ de la table « ouvrages » :

    id auteur titre url
    1 Victor Hugo Les misérables https://quelquepart.com/lmis.html

    … ça, c'est vraiment la chose à ne pas faire du tout avec un SGBD. Surtout si c'est pour éviter d'avoir à faire une jointure qui, dans ce cas particulier, resterait à la fois le plus simple et le plus indiqué.

Discussions similaires

  1. comment lister les tables et leur identifiants
    Par jclyon dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 25/07/2006, 22h03
  2. Comment rafraichir les tables directement après un INSERT ou UPDATE
    Par forzaxelah dans le forum Bases de données
    Réponses: 4
    Dernier message: 20/07/2006, 15h01
  3. Réponses: 15
    Dernier message: 22/06/2006, 16h17
  4. [ADO.NET][IDbDataAdapter] Comment nommer les tables dans un dataset ?
    Par davcha dans le forum Accès aux données
    Réponses: 11
    Dernier message: 11/05/2006, 17h42
  5. [Sql] Comment lister les tables d'une base ?
    Par Mynautor dans le forum DB2
    Réponses: 6
    Dernier message: 05/09/2005, 13h21

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