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 :

Mettre une condition dans la partie ON(jointure) ou where?


Sujet :

Développement SQL Server

  1. #1
    Membre confirmé
    Inscrit en
    Novembre 2010
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 80
    Par défaut Mettre une condition dans la partie ON(jointure) ou where?
    Bonjour,
    SVP,j'aimerai comprendre la différence entre mettre une condition dans la partie on ou where?parceque j'ai remarqué que des fois il n y a pas de difference et des fois l'emplacement de la condition retourne deux resultats diffirents?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    table produit
    id_produit 
    nom_produit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    table Produit_vendus
    id_facture
    id_produit
    quantité
    qu'elle est la difference entre les deux requetes malgre que leurs resultats est identique
    requete 1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    select a.*
    from produit a
    inner join Produit_vendus b
    on a.id_produit=b.id_produit and b.quantite>100
    requete 2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select a.*
    from produit a
    inner join Produit_vendus b
    on a.id_produit=b.id_produit
    Where b.quantite>100
    Merci d'avance

  2. #2
    Membre éclairé
    Homme Profil pro
    SQL Server
    Inscrit en
    Juin 2010
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : SQL Server
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2010
    Messages : 43
    Par défaut
    Bonjour
    Dans ta requête, il n'y a pas de différence, il peut y avoir une différence de résultat sur l'emplacement de prédicat dans les requête avec des jointures externes (LEFT JOIN, RIGHT JOIN, FULL JOIN).
    Le résultat avec une jointure externe génère du NULL, du coup en filtrant dans le WHERE ça fait sortir les valeurs null, dans le ON ça laisse la valeur NULL + le résultat du WHERE.

  3. #3
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Par défaut
    Ce n'est effectivement pas la même chose.
    Aussi, c'est plus parlant avec des LEFT JOIN (plutôt que des INNER JOIN).

    Quelques exemples...

    1. Ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT *
    FROM produit A
    LEFT JOIN Produit_vendus B
        ON  (A.id_produit = B.id_produit
        AND B.quantite > 100)
    ...devrait retourner le même résultat que cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT *
    FROM produit A
    LEFT JOIN (
        SELECT *
        FROM Produit_vendus
         B.quantite > 100
    ) B
        ON (A.id_produit = B.id_produit)


    2. Il est possible de faire des jointures uniquement sous certaines conditions :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT *
    FROM produit A
    LEFT JOIN Produit_vendus B
        ON  (A.nom_produit LIKE 'abc%'
        AND A.id_produit = B.id_produit)
    Ici, on effectue la jointure que pour les enregistrements de A dont le champs "nom_produit" commence par "abc".
    Pour les enregistrements de A dont le champs "nom_produit" ne commence pas par "abc", les champs de B apparaîtront comme NULL.

    Ça m'est arrivé une fois, on m'a demandé de faire une vue avec plein de cas particuliers (en partant d'une table A, suivant les valeurs de certains champs de A, on va chercher des informations complémentaires dans les table B ou C ou D ou E...).

    J'avais le choix entre une requête avec plein d'UNIONs et des conditions partout :
    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
    SELECT a.id, a.foo, a.bar, b.val AS valB, CAST(NULL AS INT) AS valC, CAST(NULL AS INT) AS valD, ...
    FROM A
    INNER JOIN B
        ON (A.id = B.id_A)
    WHERE a.foo IN (1, 2)
     
    UNION ALL
     
    SELECT a.id, a.foo, a.bar, NULL, c.val, NULL, ...
    FROM a
    INNER JOIN c
        ON (a.id = c.id_A)
    WHERE a.bar IN (2, 3, 4)
     
     
    UNION ALL
    ...
    ...ou alors faire une requête avec des conditions dans les jointures :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT a.id, a.foo, a.bar, a.val AS val1, c.val AS valC, d.val AS valD, ...
    FROM a
    LEFT JOIN b
        ON (a.foo IN (1, 2)
        AND a.id = b.id_A)
     
    LEFT JOIN c
        ON (a.bar IN (2, 3, 4)
        AND a.id = c.id_A)
    ...
    La deuxième avait beaucoup d'avantages :
    - plus lisible
    - pour certaines valeurs (a.foo = 2, a.bar = 3), on se retrouve avec des cas complexes qu'il faut gérer (doublons). Avec la deuxième solution, c'est plus beaucoup plus simple à gérer (on spécifie exactement dans quelles conditions la jointure doit avoir lieu)
    - si on a des index sur les champs ayant une condition dans la jointure (a.foo, a.bar), et que ceux-ci sont suffisamment discriminants pour les valeurs qui nous intéressent, alors SQL Server arrive à optimiser

    Voilà, c'étaient deux exemple de conditions dans une jointure :
    1. condition sur des champs de la table de droite
    2. condition sur des champs de la table de gauche

    ...ainsi que des équivalents sans condition dans la jointure, mais dans le WHERE (et des UNIONs à vous rendre fou)
    "On en a vu poser les armes avant de se tirer une balle dans le pied..."
    -- pydévelop

    Derniers articles:

    (SQL Server) Introduction à la gestion des droits
    (UML) Souplesse et modularité grâce aux Design Patterns
    (UML) Le Pattern Etat
    Autres articles...

  4. #4
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Pour des raisons de compatibilité, il vaut mieux éviter les valeurs littérales dans la clause ON.

    En effet, Access par exemple, mais aussi certaines vieilles versions d'Oracle notamment, ne supportent pas de valeurs littérales dans le ON :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select *
    from tableA A
    iner join tableB B on B.col1 = A.col1 and B.col2 = 'Z'
    => Plante

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    select *
    from tableA A
    iner join tableB B on B.col1 = A.col1
    WHERE B.col2 = 'Z'
    => Fonctionne

    Donc en présence d'une telle restriction, bien réfléchir si la valeur littérales est réellement nécessaire, car si le code doit être porté sur Access par exemple, il faudra passer par une vue, ce qui obligera à réécrire une partie du code inutilement.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. UI Dialog, mettre une condition dans "buttons"
    Par baggie dans le forum jQuery
    Réponses: 2
    Dernier message: 04/11/2010, 11h09
  2. Mettre une condition dans une action
    Par barouz dans le forum Servlets/JSP
    Réponses: 6
    Dernier message: 24/04/2007, 11h24
  3. [C# 2.0]Mettre une condition dans un repeater
    Par giloutho dans le forum ASP.NET
    Réponses: 1
    Dernier message: 07/11/2006, 19h13
  4. mettre une condition dans l'ajout de données
    Par ash_rmy dans le forum Access
    Réponses: 2
    Dernier message: 27/07/2006, 13h29
  5. Mettre une condition if dans une requete sql
    Par Sardonnen dans le forum Oracle
    Réponses: 4
    Dernier message: 24/03/2006, 11h25

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