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

Développement SQL Server Discussion :

*= et left outer join


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau candidat au Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 1
    Par défaut *= et left outer join
    bonjour,

    je migre actuellemnt une base sql7 vers Sql 2005, et rencontre un pb avec une procedure en syntaxe *= convertie en left outer join pour être compatible avec sql 20005

    SQL7:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    from cotis C, Adh_cot A 
    where VA = 1 and A.no_a = @adh 
    and c.cf = 0 
    and c.n_cot *= a.no_cot
    que j'ai traduit pour sql2005 en:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    from cotis C left outer join Adh_cot A on 
    c.no_cot = A.no_cot
    where VA = 1 and A.no_A = @adh
    and c.cf = 0
    Je n'obtiens pas le même resultat....(plus de lignes en sql7).

    quelqu'un peut m'aider (je ne suis pas du tout spécialiste en sql...)

    Merci

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 26
    Par défaut
    Bonjour,

    essayez plutôt :
    FROM cotis C
    LEFT OUTER JOIN Adh_cot A ON c.no_cot = A.no_cot AND c.cf = 0
    WHERE VA = 1 AND A.no_A = @adh
    en supossant que VA = 1 appartienne à Adh_cot dans le cas contraire

    FROM cotis C
    LEFT OUTER JOIN Adh_cot A ON c.no_cot = A.no_cot AND VA = 1 AND c.cf = 0
    WHERE A.no_A = @adh
    tenez moi au courant

    Cordialement

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 010
    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 : 22 010
    Billets dans le blog
    6
    Par défaut
    Depuis des années MS conseille de passer aux OUTER JOIN..... les jointures externes ancienne mode donnent effectivement des résultats mathématiquement faux. Lisez la démonstration que j'ai donné dans mon blog :
    http://blog.developpez.com/sqlpro/p5...-et-le-nouvea/

    Il n'y a donc pas de solution à votre problème, autre que fonctionnelle !!!!!

    Ne connaissant pas votre problème (vous ne dites pas POURQUOI c'est faux), je vous suggère néanmoins de mettre vos filtres dans le prédicat de jointure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    FROM cotis C
         LEFT OUTER JOIN Adh_cot A 
              ON c.no_cot = A.no_cot 
                 AND c.cf = 0
                 AND VA = 1 
                 AND A.no_A = @adh

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

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 26
    Par défaut
    Bonjour,

    Effecivement Frédéric BROUARD, reprends et complète ma précédente réponse.
    Par contre je ne suis pas favorable à intégrer dans la clause de jointure les filtres qui pour moi et pour rester plus claire (visuellement à mon sens ) doivent resté dans la clause WHERE
    c'est donc pour cela que je lui est proposé les deux solutions en fonction de sa situation fonctionnelle.

  5. #5
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 010
    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 : 22 010
    Billets dans le blog
    6
    Par défaut
    Par contre je ne suis pas favorable à intégrer dans la clause de jointure les filtres qui pour moi et pour rester plus claire (visuellement à mon sens ) doivent resté dans la clause WHERE
    Vous faites erreurs, car les deux choses ne sont pas équivalentes... Loin s'en faut !

    Démonstration :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE T_CLIENT
    (CLI_ID     INT PRIMARY KEY,
     CLI_NOM    VARCHAR(16))
     
    CREATE TABLE T_TELEPHONE
    (TEL_ID     INT PRIMARY KEY,
     CLI_ID     INT FOREIGN KEY REFERENCES T_CLIENT (CLI_ID),
     TEL_NUM    VARCHAR(16),
     TEL_TYPE   CHAR(3))
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    INSERT INTO T_CLIENT VALUES (1, 'DUVAL')
    INSERT INTO T_CLIENT VALUES (2, 'DUPONT')
    INSERT INTO T_CLIENT VALUES (3, 'DUFOUR')
    INSERT INTO T_CLIENT VALUES (4, 'DUMOULIN')
     
    INSERT INTO T_TELEPHONE VALUES (1, 1, '0123456789', 'TEL')
    INSERT INTO T_TELEPHONE VALUES (2, 1, '9876543210', 'FAX')
    INSERT INTO T_TELEPHONE VALUES (3, 2, '7418529630', 'TEL')
    INSERT INTO T_TELEPHONE VALUES (4, 3, '0147258369', 'FAX')
    Cette première requête correspond en fait à une jointure interne car la table en jointure externe est refiltrée par le WHERE...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT * 
    FROM   T_CLIENT AS C
           LEFT OUTER JOIN T_TELEPHONE AS T
                ON C.CLI_ID = T.CLI_ID
    WHERE  TEL_TYPE = 'FAX'
    Résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CLI_ID      CLI_NOM          TEL_ID      CLI_ID      TEL_NUM          TEL_TYPE
    ----------- ---------------- ----------- ----------- ---------------- --------
    1           DUVAL            2           1           9876543210       FAX
    3           DUFOUR           4           3           0147258369       FAX
    D'ou votre idée de demander le IS NULL en "ou" en sus du filtre WHERE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT * 
    FROM   T_CLIENT AS C
           LEFT OUTER JOIN T_TELEPHONE AS T
                ON C.CLI_ID = T.CLI_ID
    WHERE  TEL_TYPE = 'FAX' OR TEL_TYPE IS NULL
    Résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CLI_ID      CLI_NOM          TEL_ID      CLI_ID      TEL_NUM          TEL_TYPE
    ----------- ---------------- ----------- ----------- ---------------- --------
    1           DUVAL            2           1           9876543210       FAX
    3           DUFOUR           4           3           0147258369       FAX
    4           DUMOULIN         NULL        NULL        NULL             NULL
    Qui, comme vous le constaterez, ne donne pas du tout le même résultat si le filtre WHERE est incorporé au prédicat de jointure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT * 
    FROM   T_CLIENT AS C
           LEFT OUTER JOIN T_TELEPHONE AS T
                ON C.CLI_ID = T.CLI_ID AND TEL_TYPE = 'FAX'
    Résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CLI_ID      CLI_NOM          TEL_ID      CLI_ID      TEL_NUM          TEL_TYPE
    ----------- ---------------- ----------- ----------- ---------------- --------
    1           DUVAL            2           1           9876543210       FAX
    2           DUPONT           NULL        NULL        NULL             NULL
    3           DUFOUR           4           3           0147258369       FAX
    4           DUMOULIN         NULL        NULL        NULL             NULL
    Je laisse à votre sagacité le soin d'essayer de comprendre ce qui se passe et ou est votre erreur !
    Il s'agit bien évidemment d'un problème de sémantique, mais en principe lorsque l'on veut une jointure externe c'est généralement pour avoir toute la table racine et les éventuelles données significatives des tables filles. C'est pourquoi il est nécessaire la plupart du temps de mettre les filtres des tables fille dans le prédicat de jointure et non dans le filtre WHERE comme vous le préconisez...
    De plus avoir un OR dans un filtre WHERE empêche toute indexation....

    Bref, une bonne révision de ce qu'est une jointure s'impose !!!

    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. Probleme de NULL avec LEFT OUTER JOIN
    Par jiluc dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 12/01/2006, 14h42
  2. Bug LEFT OUTER JOIN Firebird
    Par Fabio2000 dans le forum SQL
    Réponses: 3
    Dernier message: 21/11/2005, 09h08
  3. Problème avec left outer join
    Par jgfa9 dans le forum Requêtes
    Réponses: 1
    Dernier message: 22/08/2005, 21h07
  4. Problème de performance avec LEFT OUTER JOIN
    Par jgfa9 dans le forum Requêtes
    Réponses: 6
    Dernier message: 17/07/2005, 13h17
  5. concatenation de chaine dans un left outer join
    Par the_edge dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 11/11/2004, 16h08

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