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 :

Jointures et valeurs Nulls


Sujet :

Langage SQL

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    iut amiens
    Inscrit en
    Mai 2013
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : iut amiens
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2013
    Messages : 43
    Points : 29
    Points
    29
    Par défaut Jointures et valeurs Nulls
    Bonjour à tous (oui encore moi ^^),

    j'ai dans une table des noms de méthode d'analyse (lié à la fonction de l'employé) qu'un employé effectue pendant ses journées de travail
    qui est relié a une autre table qui contient les tâches réalisées par l'employé en fonction de la méthode.

    Cependant il arrive que par exemple l'employé effectue une tâche qui ne soit pas en relation avec une méthode analytique

    est-ce judicieux de mettre comme valeur : "NULL" à la méthode indiqué?

    par exemple:
    NumFonction NumMethode Methode Tache
    6 5 NULL tache1
    6 6 NULL Tache2
    7 7 Methode7 Tache3


    Parce que j'ai essayé d'extraire mes données Methodes, Tache là ou le NumFoncion=6 par cette requête:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT NomMethode, NomTache
    	  FROM Ordonner
    			JOIN Tache ON Ordonner.NumTache=Tache.NumTache
    			JOIN Methode ON Tache.NumMethode=Methode.NumMethode			
              WHERE Methode.NumFonction=6
    Et cette requête ne renvoie que la méthode 5 et pas la méthode 6.

    une petite idée?

  2. #2
    Membre habitué Avatar de Razorflak
    Homme Profil pro
    Développeur Flex/AS3
    Inscrit en
    Juin 2013
    Messages
    97
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Flex/AS3
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2013
    Messages : 97
    Points : 192
    Points
    192
    Par défaut
    Bonjour,

    En remplaçant tes par des ça devrait résoudre ton problème.
    Pour plus de détails sur les jointures, je te conseil les cours de SQLPro: http://sqlpro.developpez.com/

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    iut amiens
    Inscrit en
    Mai 2013
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : iut amiens
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2013
    Messages : 43
    Points : 29
    Points
    29
    Par défaut
    J'ai déjà essayé LEFT JOIN, LEFT OUTER JOIN, ça ne marche pas.

    J'avais pensé que ça venais de ma base de donnée qui avait de mauvaises données,
    mais non les données sont bonnes... je vais regarder du côte de SQL pro,

    si vous avez encore des idées n'hésitez pas !

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    iut amiens
    Inscrit en
    Mai 2013
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : iut amiens
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2013
    Messages : 43
    Points : 29
    Points
    29
    Par défaut
    Ah en lisant le cours de SQL pro j'ai mieux compris les jointures externes !

    il suffisait de mettre des et cela à suffit.

    Merci !

    EDIT: Par contre par exemple si je veux associé plus de données qui sont associés aux méthodes et aux analyse, apparemment cela ne marche pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT NomTache, NomProduit, PhraseRisque, DescriptionMode, Quantite, NomUniteQ, Duree, NomUniteD, NomVoieExp
    		FROM Ordonner
    					RIGHT OUTER	JOIN Tache ON Ordonner.NumTache=Tache.NumTache
    					RIGHT OUTER	JOIN Methode ON Tache.NumMethode=Methode.NumMethode
    					JOIN Mode ON Ordonner.NumMode=Mode.NumMode
    					JOIN UniteQ ON Ordonner.NumUniteQ= UniteQ.NumUniteQ
    					JOIN UniteD ON Ordonner.NumUniteD= UniteD.NumUniteD
    					JOIN VoieExpositions ON Ordonner.NumVoie=VoieExpositions.NumVoie
    					JOIN Fonction ON Methode.NumFonction=Fonction.NumFonction
    					JOIN Produit ON Ordonner.NumProduit=Produit.NumProduit
     
    		WHERE Methode.NumFonction=6;

  5. #5
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Une jointure interne dont la condition fait référence à une table en jointure externe casse l'effet de la jointure externe, puisque NULL n'est égal à rien...

    Il faut donc imbriquer vos jointures internes à vos jointures externes, ou, dans votre cas, modifier l'ordre des jointures :

    ceci doit être suffisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    SELECT NomTache, NomProduit, PhraseRisque, DescriptionMode, Quantite, NomUniteQ, Duree, NomUniteD, NomVoieExp
    		FROM Ordonner
    					JOIN Mode ON Ordonner.NumMode=Mode.NumMode
    					JOIN UniteQ ON Ordonner.NumUniteQ= UniteQ.NumUniteQ
    					JOIN UniteD ON Ordonner.NumUniteD= UniteD.NumUniteD
    					JOIN VoieExpositions ON Ordonner.NumVoie=VoieExpositions.NumVoie
    					JOIN Produit ON Ordonner.NumProduit=Produit.NumProduit
    					RIGHT OUTER	JOIN Tache ON Ordonner.NumTache=Tache.NumTache
    					RIGHT OUTER	JOIN Methode ON Tache.NumMethode=Methode.NumMethode
    					JOIN Fonction ON Methode.NumFonction=Fonction.NumFonction
     
     
    		WHERE Methode.NumFonction=6;

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    iut amiens
    Inscrit en
    Mai 2013
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : iut amiens
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2013
    Messages : 43
    Points : 29
    Points
    29
    Par défaut
    Ah merci! Cependant, ça m'affiche juste les Taches correctement, les autres champs sont tous à NULL :/

    Je ne savais pas qu'il y avait un ordre a respecter ^^.

    Merci pour ton aide !

    EDIT : La seule manière pour le SQL de mettre des valeurs NULL dans ces champs c'est de mettre les valeurs des méthodes a NULL correspondante...

  7. #7
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    NULL n'est pas une valeur, mais plutôt l'absence d'une valeur.

    Il faut voir ça comme un état indéfini.

    De ce fait il ne peut être évalué à de "vrai" valeur.


    Lorsque l'on veut tester si une colonne possède des NULL on utilise en SQL : ma_col IS NULL

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    iut amiens
    Inscrit en
    Mai 2013
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : iut amiens
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2013
    Messages : 43
    Points : 29
    Points
    29
    Par défaut
    Bonjour Punkoff,

    Oui, c'était une manière de parler ! mais normalement dans ma base de donnée tout est bien rempli donc tous les champs qui sont a NULL

    C'est à dire Produit, Phrase Risque, Mode d'utilisation, Quantité, Durée, Voie d'exposition... je ne vois pas comment faire pour que ma requête affiche tout bien :/

    J'ai essayé ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT NomTache, NomProduit, PhraseRisque, DescriptionMode, Quantite, NomUniteQ, Duree, NomUniteD, NomVoieExp
    		FROM Ordonner
    					JOIN Mode ON Ordonner.NumMode=Mode.NumMode
    					LEFT OUTER JOIN UniteQ ON Ordonner.NumUniteQ= UniteQ.NumUniteQ
    					LEFT OUTER JOIN UniteD ON Ordonner.NumUniteD= UniteD.NumUniteD
    					LEFT OUTER JOIN VoieExpositions ON Ordonner.NumVoie=VoieExpositions.NumVoie
    					LEFT OUTER JOIN Produit ON Ordonner.NumProduit=Produit.NumProduit
    					RIGHT OUTER JOIN Tache ON Ordonner.NumTache=Tache.NumTache
    					RIGHT OUTER JOIN Methode ON Tache.NumMethode=Methode.NumMethode
    					 JOIN Fonction ON Methode.NumFonction=Fonction.NumFonction
     
    		WHERE Methode.NumFonction=6;
    ça m'affiche 1 ligne avec la bonne tache mais les mauvaises valeurs associés.

    Je ne comprends vraiment pas ...

  9. #9
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par kaela Voir le message
    Cependant, ça m'affiche juste les Taches correctement, les autres champs sont tous à NULL :/
    Sauf pour les lignes qui pour lesquelles les colonnes de la table "Ordonner" ne sont pas null.
    C'est normal !

    Lorsque vous faites
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    FROM Ordonner
    	RIGHT OUTER	JOIN Tache ON Ordonner.NumTache=Tache.NumTache
    Les lignes de la tables Tache pour lesquelles il n'y a pas de correspondance dans la table Ordonner ressortent quand même (du fait de la jointure externe), mais les colonnes de la table Ordonner sont toutes à NULL.

    De fait, si vous ajoutez une jointure interne avec une autre table, et que la condition de jointure contient un test d'égalité sur une des colonnes de la table "Ordonner", alors, vous comparez avec un NULL, ce qui ne peut jamais être vrai.

    Ce qui répond à votre deuxième interrogation :
    Citation Envoyé par kaela Voir le message
    Je ne savais pas qu'il y avait un ordre a respecter ^^.
    Si vous faites votre jointure interne après votre jointure externe, alors comme il n'y a pas de correspondance, les lignes ne sont pas conservées. (il faudrait sinon faire également une jointure externe, mais gauche cette fois...).

    Si vous faites votre jointure interne avant la jointure externe droite, alors, de la même façon, toutes les colonnes de toutes les tables jointes précédemment seront à NULL, comme vous avez pu le constater.

  10. #10
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par kaela Voir le message
    mais normalement dans ma base de donnée tout est bien rempli
    Justement non !

    Certaines ligne de la table tache ne sont rattachées à aucune ligne de la table Ordonner. ce qui provoque le résultat que vous obtenez.

    en effet, comme presque toutes les autres table sont rattachée à la table Ordonner, vous ne pouvez pas retrouver les informations.
    Ou alors, il faudrait que les jointures avec les autres tables ne portent pas sur la table Ordonner...

    Du coup, je me pose des questions quant à votre schéma... pourriez vous nous le fournir ? (graphique, ou sous forme de CREATE TABLE)

  11. #11
    Nouveau membre du Club
    Homme Profil pro
    iut amiens
    Inscrit en
    Mai 2013
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : iut amiens
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2013
    Messages : 43
    Points : 29
    Points
    29
    Par défaut
    Voilà mon fichier de création de table CreationTable.sql

    j'ai vérifié et mon insertion de table est bonne ^^. Chaque clef pointe bien vers une autre clef

  12. #12
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    C'est donc dans votre table "Tache" que la colonne NumMethode est laissée à NULL lorsque l'employé effectue une tache qui n'est pas en relation avec une méthode ?

    Si c'est le cas, c'est bien des jointures externes gauches (et non droites) qu'il vous fallait...


    Que donne ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT NomTache, NomProduit, PhraseRisque, DescriptionMode, Quantite, NomUniteQ, Duree, NomUniteD, NomVoieExp
    FROM Ordonner
    	JOIN Mode ON Ordonner.NumMode=Mode.NumMode
    	JOIN UniteQ ON Ordonner.NumUniteQ= UniteQ.NumUniteQ
    	JOIN UniteD ON Ordonner.NumUniteD= UniteD.NumUniteD
    	JOIN VoieExpositions ON Ordonner.NumVoie=VoieExpositions.NumVoie
    	JOIN Produit ON Ordonner.NumProduit=Produit.NumProduit
    	JOIN Tache ON Ordonner.NumTache=Tache.NumTache
    	LEFT OUTER JOIN Methode ON Tache.NumMethode=Methode.NumMethode
    	LEFT OUTER JOIN Fonction ON Methode.NumFonction=Fonction.NumFonction
     WHERE Methode.NumFonction=6;
    Cependant :
    1/ Je me demande pourquoi la table Ordonner contient la colonne NumProduit, les produit étant déjà rattachés aux taches par une table associative.
    2/ Par ailleurs, vous autorisez les NULL partout. Ce n'est pas une très bonne idée. Spécifiez NOT NULL lors de la création des tables pour les colonnes qui doivent être renseignées. Du coup, il vous faudrait des jointures externes exclusivement...

    Si la requête n'est toujours pas bonne, pourriez vous fournir un jeu de données également ?

  13. #13
    Nouveau membre du Club
    Homme Profil pro
    iut amiens
    Inscrit en
    Mai 2013
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : iut amiens
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2013
    Messages : 43
    Points : 29
    Points
    29
    Par défaut
    Bonjour, la requête que tu m'as fourni ne fonctionne pas.

    c'est dans méthodes où il peut y avoir des nom de méthode null, Tache, et Produits sont toujours renseigné

    Dans la table tâche on a le numéro de la méthode, donc ce numéro n'est jamais null, la méthode a une clef qui pointe vers le numéro de fonction de l'employé.
    Donc en fait la la table tache il n'y a aucun NULL, c'est bien dans la méthode qu'il y a des NULL.

    Et Concernant le numéro produit dans concerner c'est normal, j'en ai besoins pour mon application ^^.

    Voici le jeu de donnée que j'utilise: jeudedonne.sql
    désolé pour le code pas très lisible je n'ai pas trouvé de moyen d'insérer mes valeurs par table avec sql 2005
    j'ai donc du mettre un insert par enregistrement...

    Dans le jeu de donnée ce qui ne va pas c'est les données pour la fonction 3, 7

    Donc a partir du numéro de fonction 6 tu passe par la table Affecter(ou on précise le dernier métier de l'employé qui est susceptible d'évoluer dans l'entreprise)
    Puis la table fonction, méthode, tache, et enfin ordonner.

    La ou ça coince c'est avec la table Methode

    Merci pour ton aide!! j'en ai vraiment besoins...

  14. #14
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Dans la table Ordonner, la colonne NumUniteQ est parfois NULL.

    Il faut donc faire une jointure externe avec cette table...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT NomTache, NomProduit, PhraseRisque, DescriptionMode, Quantite, NomUniteQ, Duree, NomUniteD, NomVoieExp
    FROM Ordonner
    	JOIN Mode ON Ordonner.NumMode=Mode.NumMode
    	LEFT JOIN UniteQ ON Ordonner.NumUniteQ= UniteQ.NumUniteQ
    	JOIN UniteD ON Ordonner.NumUniteD= UniteD.NumUniteD
    	JOIN VoieExpositions ON Ordonner.NumVoie=VoieExpositions.NumVoie
    	JOIN Produit ON Ordonner.NumProduit=Produit.NumProduit
    	JOIN Tache ON Ordonner.NumTache=Tache.NumTache
    	JOIN Methode ON Tache.NumMethode=Methode.NumMethode
    	JOIN Fonction ON Methode.NumFonction=Fonction.NumFonction
     WHERE Methode.NumFonction=6;
    Comme je disais, vu que toutes vos clefs étrangères sont nullables, il faudrait faire des jointures externes systématiquement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT NomTache, NomProduit, PhraseRisque, DescriptionMode, Quantite, NomUniteQ, Duree, NomUniteD, NomVoieExp
    FROM Ordonner
    	LEFT JOIN Mode ON Ordonner.NumMode=Mode.NumMode
    	LEFT JOIN UniteQ ON Ordonner.NumUniteQ= UniteQ.NumUniteQ
    	LEFT JOIN UniteD ON Ordonner.NumUniteD= UniteD.NumUniteD
    	LEFT JOIN VoieExpositions ON Ordonner.NumVoie=VoieExpositions.NumVoie
    	LEFT JOIN Produit ON Ordonner.NumProduit=Produit.NumProduit
    	LEFT JOIN Tache ON Ordonner.NumTache=Tache.NumTache
    	LEFT JOIN Methode ON Tache.NumMethode=Methode.NumMethode
    	LEFT JOIN Fonction ON Methode.NumFonction=Fonction.NumFonction

  15. #15
    Nouveau membre du Club
    Homme Profil pro
    iut amiens
    Inscrit en
    Mai 2013
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : iut amiens
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2013
    Messages : 43
    Points : 29
    Points
    29
    Par défaut
    Oh ça marche !!! MERCI énormément !!!

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

Discussions similaires

  1. [requete] JOINTURE et valeur null
    Par jeepibmx dans le forum SQL
    Réponses: 6
    Dernier message: 18/07/2008, 07h37
  2. [REQUETE] jointure et valeur 'null'
    Par jeepibmx dans le forum Langage SQL
    Réponses: 10
    Dernier message: 17/07/2008, 19h12
  3. [windev12]jointure et valeur null
    Par nath-0-0 dans le forum WinDev
    Réponses: 4
    Dernier message: 22/05/2008, 21h41
  4. Jointure et valeur NULL
    Par BiM dans le forum Langage SQL
    Réponses: 6
    Dernier message: 23/05/2005, 16h26
  5. Type de jointure et valeur NULL
    Par HULK dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 19/01/2005, 14h22

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