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

Requêtes PostgreSQL Discussion :

Problème syntaxe - Jointure reflexive


Sujet :

Requêtes PostgreSQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Analyse système
    Inscrit en
    Juin 2018
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Analyse système
    Secteur : Alimentation

    Informations forums :
    Inscription : Juin 2018
    Messages : 180
    Par défaut Problème syntaxe - Jointure reflexive
    Bonjour à tous,

    Ayant commencé à apprendre les jointures avec la formule NATURAL JOIN, je me demandais quelle devait être la syntaxe d'une jointure reflexive cette dernière.

    Ainsi, j'aimerais transformer cette requete qui affiche les employes et leur supérieur hiérarchique, avec une Natural join :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select a.nom, a.prenom, b.nom as nom_superieur, b.prenom as prenom_superieur
    from employe a, employe b
    where (a.dependde = b.employeid)
    Merci à vous.

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 610
    Billets dans le blog
    10
    Par défaut
    bonjour,

    Evitez les NATURAL JOIN c'est une jointure instable et donc très dangereuse : la jointure se fait automatiquement entre les colonnes de même nom des différentes tables ou vues, si les tables ou les vues utilisées sont modifiées pour y ajouter des colonnes, le résultat de la jointure peut changer. À fuir comme la peste donc.

    Sinon, pour les jointures explicites, utilisez l'opérateur JOINcomme suit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    select a.nom
         , a.prenom
         , b.nom as nom_superieur
         , b.prenom as prenom_superieur
    from employe a
    left join employe b
      on a.dependde = b.employeid
    Ici j'ai utilisé une jointure OUTER car il est possible qu'une personne n'ait pas de supérieur (le big boss quoi )
    Avec une jointure à l'ancienne telle que vous l'avez codée (jointure dans la clause WHERE) ou une jointure INNER JOIN qui est équivalente, seuls les employés qui ont un supérieur hiérarchique seront récupérés


    Si vous voulez vous perfectionner sur les jointures, jetez un coup d'oeil ICI

  3. #3
    Membre confirmé
    Homme Profil pro
    Analyse système
    Inscrit en
    Juin 2018
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Analyse système
    Secteur : Alimentation

    Informations forums :
    Inscription : Juin 2018
    Messages : 180
    Par défaut
    Un grand merci à vous pour ces explications claires et précises

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 999
    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 999
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    bonjour,

    Evitez les NATURAL JOIN c'est une jointure instable et donc très dangereuse
    Non seulement je plussois mais en sus les performances sont catastrophiques car cela provoque des jointures triangulaires quadrangulaire... qui sont totalement inoptimiSable, laissant le SGBDR faire des boucles imbriquées de boucles imbriquées de boucles imbriquées.....

    Certaines SGBDR intelligent ont purement et simplement interdit le NATURAL JOIN (en particulier Microsoft SQL Server)....

    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/ * * * * *

  5. #5
    Expert confirmé
    Avatar de pachot
    Homme Profil pro
    Developer Advocate YugabyteDB
    Inscrit en
    Novembre 2007
    Messages
    1 822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Developer Advocate YugabyteDB
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 822
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    les performances sont catastrophiques
    C'est une variante de syntaxe. Aucun rapport avec la performance. Le plan d'exécution sera toujours une jointure et la méthode sera choisie par l'optimiseur.


    Citation Envoyé par escartefigue Voir le message
    c'est une jointure instable et donc très dangereuse
    Non, pas si on maitrise les projections


    La question est: comment écrire la même requête avec un natural join.

    La réponse est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    select nom, prenom, nom_superieur, prenom_superieur
    from (
     select nom, prenom
     ,dependde
     from employe
    ) natural inner join (
     select nom as nom_superieur, prenom as prenom_superieur
     ,employeid as dependde
     from employe
    ) superieur
    On peut trouver ceci plus lisible, ou moins, mais ce n'est ni dangereux, ni instable, ni triangulaire quadrangulaire , ni catastrophique, ni moins intelligent...

  6. #6
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 610
    Billets dans le blog
    10
    Par défaut
    Utiliser des tables dérivées pour contrer les défauts d'une jointure "naturelle" est une astuce amusante, mais je doute qu'elle corresponde à ce que l'on rencontre dans la nature
    Et je n'en vois pas l'intérêt : c'est ajouter une étape supplémentaire, rendre l'écriture de la requête plus lourde et utiliser une syntaxe non supportée par tous les SGBD (NATURAL JOIN n'est pas implémenté partout)

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 999
    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 999
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par pachot Voir le message
    C'est une variante de syntaxe. Aucun rapport avec la performance. Le plan d'exécution sera toujours une jointure et la méthode sera choisie par l'optimiseur.

    Non, pas si on maitrise les projections
    Franck, je t'aime bien, mais ce que tu dis est faux....

    En effet, ce que tu affirme peut être vrai, si 3 conditions sont respectées :
    1) toutes les tables sont liées par l'intégrité référentielles déclarative entre les références et les clef étrangères
    2) toutes les jointures sont établies par rapport aux liens d'intégrité référentielle déclarative et non sur des colonnes "libres"
    3) l'optimiseur sait tirer partie des contraintes d'intégrité référentielle déclarative (optimisation sémantique)

    Dans tous les autres cas, c'est catastrophique !

    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/ * * * * *

  8. #8
    Expert confirmé
    Avatar de pachot
    Homme Profil pro
    Developer Advocate YugabyteDB
    Inscrit en
    Novembre 2007
    Messages
    1 822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Developer Advocate YugabyteDB
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 822
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    Utiliser des tables dérivées pour contrer les défauts d'une jointure "naturelle"
    Il ne s'agit pas de tables dérivées. Seulement d'appliquer la projection avant la jointure. Avec cette écriture, aucun problème d'alias de tables (les 'a' et 'b' de la requête initiale qui ne sont pas très parlants car lorsqu'on doit les répeter devant toutes les colonnes, on se retrouve a prendre un nom abstrait court). Il peut être très logique et très lisible d'écrire une requête complexe de cette manière. Car on projette chaque colonne sur le résultat final au fur et à mesure qu'on déclare les tables.
    Ici: je lis 'employé' en tant que subalterne dans mon résultat. Puis je lis 'employé' en tant que supérieur dans mon résultat. Et la jointure se fait toute seule.

    Encore une fois, c'est au choix. Mais il y en a qui trouveront ceci beaucoup plus lisible et maintenable ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    with
    subordonne as ( -- ceci est ma liste d'employés en tant que subordonné
     select nom, prenom
     , dependde as employeid_superieur
     from employe
    ),
    superieur as ( -- ceci est ma liste d'employés en tant que supérieur
     select nom as nom_superieur, prenom as prenom_superieur
     ,employeid as employeid_superieur
     from employe
    )
    select nom, prenom, nom_superieur, prenom_superieur
    from subordonne natural inner join superieur
    Et même si l'écriture est différente, c'est exactement la même chose à l'exécution.

    Citation Envoyé par SQLpro Voir le message
    ...contraintes d'intégrité référentielle déclarative...optimisation sémantique...
    Il suffit de lire la doc (NATURAL is a shorthand form of USING) et tester (pour voir que le plan d'exécution est exactement le même):
    https://dbfiddle.uk/?rdbms=postgres_...d07a4a1a87cad6


    Il ne s'agit que de syntaxe différent pour exprimer la même sémantique. Bien avant une quelconque optimisation.


    La question originale était d'écrire la requête avec un Natural Join. Pourquoi ne pas juste répondre à la question et laissez l'auteur juger si c'est plus lisible, ou plus dangereux. Au lieu de l'induire en erreur avec des opinions non vérifiées?

Discussions similaires

  1. [2.x] QueryBuilder : jointure problème syntaxe
    Par hx.jonathan dans le forum Symfony
    Réponses: 8
    Dernier message: 16/11/2011, 19h28
  2. problèmes de syntaxe jointure de 3 tables
    Par mikoukoumi dans le forum Requêtes
    Réponses: 4
    Dernier message: 27/05/2011, 14h56
  3. problème syntaxe sql
    Par mpat dans le forum ASP
    Réponses: 6
    Dernier message: 01/02/2005, 19h28
  4. Pb Jointure reflexive et champ NULL
    Par VincentR dans le forum SQL
    Réponses: 8
    Dernier message: 19/01/2005, 14h14
  5. Problème de jointure ?!
    Par ebaynaud dans le forum Langage SQL
    Réponses: 8
    Dernier message: 03/11/2004, 11h27

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