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

MS SQL Server Discussion :

Ordre entre les Outer Join


Sujet :

MS SQL Server

  1. #1
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    729
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 729
    Points : 1 414
    Points
    1 414
    Par défaut Ordre entre les Outer Join
    Quelle différence de logique de traitement voyez vous entre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT *
    FROM entiers E
    RIGHT JOIN Pairs P ON P.valeur= E.valeur
    RIGHT JOIN impairs I ON I.valeur= E.valeur
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT *
    FROM entiers E
    RIGHT JOIN impairs I ON I.valeur= E.valeur
    RIGHT JOIN Pairs P ON P.valeur= E.valeur
    ?

    De manière étrange les 2 requêtes :
    1- produisent des résultats
    2- produisent des résultats différents
    3- ne produisent pas de résultat logique par rapport à l'écriture

    *****
    Pour ceux qui veulent s'amuser :
    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
     
    CREATE TABLE Entiers (valeur int) ;
    GO
    CREATE TABLE Pairs (valeur int);
    GO
    CREATE TABLE impairs (valeur int);
     
    GO
    INSERT INTO Entiers VALUES (0),(1),(2);
    INSERT INTO Pairs VALUES (0),(2),(4),(6),(8);
    INSERT INTO impairs VALUES (0),(1),(3),(5),(7),(9);
     
    SELECT *
    FROM entiers E
    RIGHT JOIN Pairs P ON P.valeur= E.valeur
    RIGHT JOIN impairs I ON I.valeur= E.valeur 
    --intersect
    SELECT *
    FROM entiers E
    RIGHT JOIN impairs I ON I.valeur= E.valeur
    RIGHT JOIN Pairs P ON P.valeur= E.valeur
    Pensez-vous que ce soit un bug dans la résolution de l'algèbre relationnel de SQL serveur ?
    Le savoir est une nourriture qui exige des efforts.

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 756
    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 756
    Points : 52 531
    Points
    52 531
    Billets dans le blog
    5
    Par défaut
    Ce résultat est parfaitement logique. Le but de la jointure externe est de préserver les lignes de la table de droite/gauche/les deux en fonction du mot clef LEFT/RIGHT/FULL.
    Mais l'opération n'est pas commutative, contrairement à l'équi-jointure interne.
    En faisant un double RIGTH OUTER JOIN, vous préservez donc la dernière opération... Pas la première !

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

  3. #3
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    729
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 729
    Points : 1 414
    Points
    1 414
    Par défaut
    Merci de ta réponse rapide.
    Cependant cela ne répond que très partiellement aux points soulevés :
    * Quelle différence de logique de traitement voyez vous ?
    * De manière étrange les 2 requêtes :
    1- produisent des résultats
    2- produisent des résultats différents
    3- ne produisent pas de résultat logique par rapport à l'écriture
    * Pensez-vous que ce soit un bug dans la résolution de l'algèbre relationnel de SQL serveur ?


    Commentaires sur ta réponse :
    Citation Envoyé par SQLpro Voir le message
    Ce résultat est parfaitement logique.
    en quoi le résultat est logique ? lequel ? le premier ou le deuxième ?
    Même si je remplace le mot "résultat" par "comportement" dans ta phrase, je n'approuve toujours pas.

    Citation Envoyé par SQLpro Voir le message
    Le but de la jointure externe est de préserver les lignes de la table de droite/gauche/les deux en fonction du mot clef LEFT/RIGHT/FULL.
    Mais l'opération n'est pas commutative, contrairement à l'équi-jointure interne.
    c'est marqué où ça ? des références ?
    Pour moi le langage SQL est de pouvoir définir le but SANS préciser le comment ; du coup la non commutativité ...
    Il n'en reste pas moins évident que est équivalent à et que bien sûr la commutation des membres doit suivre le "sens" de la jointure. On ne va pas reprendre ici les bases du langage !

    Citation Envoyé par SQLpro Voir le message
    En faisant un double RIGTH OUTER JOIN, vous préservez donc la dernière opération... Pas la première !
    Et pourquoi la dernière et pas celle du milieu ?
    Qu'est ce qu'on fait de la première et des autres ?
    Avec les resultset à l'appuis, merci de détailler ce qu'on garde et ce qu'on garde pas...


    Citation Envoyé par SQLpro Voir le message
    A +
    j'espère bien
    Le savoir est une nourriture qui exige des efforts.

  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 756
    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 756
    Points : 52 531
    Points
    52 531
    Billets dans le blog
    5
    Par défaut
    Il serait peut être bon pour vous de commencer par apprendre le langage SQL, parce que là c'est un cous complet qu'il vous faut, et non pas un tuto a la con, comme on en trouve beaucoup sur Internet !

    Pour comprendre par vous même, il suffit de décomposer... :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT *
    FROM   (SELECT E.valeur AS E_valeur, P.valeur AS P_valeur     
            FROM   entiers AS E
                   RIGHT OUTER JOIN Pairs AS P 
    	                 ON P.valeur= E.valeur) AS T 
           RIGHT OUTER JOIN impairs AS I 
    	         ON I.valeur= T.E_valeur;
    =>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT E.valeur AS E_valeur, P.valeur AS P_valeur     
    FROM   entiers AS E
           RIGHT OUTER JOIN Pairs AS P 
                 ON P.valeur= E.valeur
    Dont le résultat T :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    e_valeur    P_valeur
    ----------- -----------
    0           0
    2           2
    NULL        4
    NULL        6
    NULL        8
    est joint comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT *
    FROM   T 
           RIGHT OUTER JOIN impairs AS I 
    	         ON I.valeur= T.E_valeur;
    À ce stade le seul élément de l'ensemble T ayant une stricte correspondance avec la table des impairs est le zéro. C'est pourquoi la solution finale montre toutes les valeurs de la table à droite avec comme seule ligne complète le zéro :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    e_valeur    P_valeur    valeur
    ----------- ----------- -----------
    0           0           0
    NULL        NULL        1
    NULL        NULL        3
    NULL        NULL        5
    NULL        NULL        7
    NULL        NULL        9
    Vous devez alors comprendre (enfin, espérons-le !) le fait que la jointure externe n'est pas commutative (si vous avez quelques notions de math, essentielles pour aborder l'informatique) !

    NOTA : il est préférable de toujours mettre le mot clef OUTER dans les jointures externe, car c'est cela qui est fondamentale à comprendre, le fait que vous faites une jointure externe !!! Jointure gauche, jointure droite étant des abréviations stupides qui ne veulet rien dire !


    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
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    729
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 729
    Points : 1 414
    Points
    1 414
    Par défaut
    Super merci pour cette explication très détaillée et didactique.

    Je n'étais jamais tombé sur ce cas de requête ; en général les outer join sont orientés de manière plus naturelle :
    A -> B -> C ou A <- B -> C mais pas A -> B <- C
    Du coup la non commutativité ne mettait jamais apparu (et je n'ai jamais rien lu à ce sujet ou alors j'ai oublié ).

    Traiter les jointures non commutatives dans l'ordre de l'écriture est donc la solution retenue par le moteur (et à partir de là peuvent en découler des options dans les plans d'exécution)

    J'ai mis pas de temps à simplifier le problème et je me suis perdu dans les considérations du code initial .

    Nota à propos de l'écriture : si les abréviations d'écriture existe c'est pour s'en servir ! Ici l'objectif était de faire le script le plus court possible.
    Mais si c'était si important, voire stupide, pourquoi le langage l'accepte ?
    Oui je me sert de *, je n'écrit pas toujours AS (notamment pour les tables, comme sous Oracle) et oui OUTER est optionnel, de plus je fais parti de ceux qui regrettent l'absence de USING dans les jointures de chez SQL server.

    Ceci étant dit, ça ne change pas le fait que la démonstration ici faite est parfaite.
    Encore merci.
    Le savoir est une nourriture qui exige des efforts.

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 756
    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 756
    Points : 52 531
    Points
    52 531
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par Michel.Priori Voir le message
    Traiter les jointures non commutatives dans l'ordre de l'écriture est donc la solution retenue par le moteur (et à partir de là peuvent en découler des options dans les plans d'exécution)
    ATTENTION : ce n'est pas un choix du moteur qui lui peut faire ce qu'il veut. C'est simplement une règle de non commutativité de l'algèbre relationnelle.
    Dans certains de mes cours avancés sur le SQL je montre comment la commutativité peut modifier le comportement d'une requête qui, pour la plupart des gens, aurait été écrite avec des sous requêtes, mais n'en a finalement pas besoin, et les performances sont bien évidemment tout autre !

    Citation Envoyé par Michel.Priori Voir le message
    Nota à propos de l'écriture : si les abréviations d'écriture existe c'est pour s'en servir ! Ici l'objectif était de faire le script le plus court possible.
    Mais si c'était si important, voire stupide, pourquoi le langage l'accepte ?
    C'est une nécessité...

    Oui je me sert de *, je n'écrit pas toujours AS (notamment pour les tables, comme sous Oracle)
    Oracle est un des SGBDR qui suit le moins la norme ce qui l'a fait rejeté depuis de nombreuses années et aujourd'hui ils s'en mordent les doigts et tente de rattraper le passé (dans la nouvelle version, il y a le support des noms de 128 caractères et les collations...). En particulier l'interdiction du AS pour les alias de table est épouvantable...
    et oui OUTER est optionnel, de plus je fais parti de ceux qui regrettent l'absence de USING dans les jointures de chez SQL server.
    Le USING peut avoir de l'intérêt, mais le NATURAL JOIN est une vaste connerie que la norme à d'ailleurs rendu obsolète dans la version suivante de sa parution à cause des dégâts que cela à occasionné !
    Ceci étant dit, ça ne change pas le fait que la démonstration ici faite est parfaite.
    Encore merci.
    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/ * * * * *

  7. #7
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    dans la nouvelle version, il y a le support des noms de 128 caractères et les collations...
    ENFIN !

  8. #8
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 756
    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 756
    Points : 52 531
    Points
    52 531
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par 7gyY9w1ZY6ySRgPeaefZ Voir le message
    ENFIN !
    Un peu tard... Les entreprises fuient Oracle !

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

Discussions similaires

  1. [2014] Comparaison entre left outer join et not in
    Par cristophe0071983 dans le forum Administration
    Réponses: 4
    Dernier message: 11/04/2017, 09h38
  2. Full Outer Join entre les dimensions
    Par JackylRadis dans le forum SSAS
    Réponses: 3
    Dernier message: 19/04/2012, 18h13
  3. Joined-subclass ==> Eviter les outer join
    Par bidi dans le forum Hibernate
    Réponses: 1
    Dernier message: 11/09/2009, 14h49
  4. Réponses: 1
    Dernier message: 15/11/2006, 15h35

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