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 :

Problème avec NOT EXISTS


Sujet :

Langage SQL

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2013
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Novembre 2013
    Messages : 3
    Points : 3
    Points
    3
    Par défaut Problème avec NOT EXISTS
    Bonjour,

    Je suis en train de faire une requête SQL plutôt complexe et j'ai un problème avec la clause not exists (j'utilise MySQL).

    Ma requête :
    Code sql : 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
    22
    23
    24
    25
    26
    27
    28
     
    SELECT 
        ZST.num_train, 
        ZSP.heure, 
        ZSP.id_prevision 
    FROM 
        zs_prevision_train ZSPT 
    LEFT JOIN 
        zs_prevision ZSP 
        ON ZSPT.id_prevision = ZSP.id_prevision 
    LEFT JOIN 
        zs_train ZST 
        ON ZSPT.id_train = ZST.id_train 
    LEFT JOIN 
        zs_historique ZSH 
        ON ZSPT.id_prevision = ZSH.id_prevision  
    WHERE 
        NOT EXISTS (SELECT zs_historique.id_prevision 
                           FROM zs_historique 
                           LEFT JOIN zs_prevision ON zs_prevision.id_prevision = zs_historique.id_historique 
                           WHERE (date = DATE_FORMAT('23/8/2015','%d/%m/%Y')
                                          and zs_prevision.heure > TIME_FORMAT('22:45','%H:%i'))
                                      OR(date = CURDATE())) 
        AND ZSPT.second_train = 0 
        AND (ZSP.heure BETWEEN TIME_FORMAT("22:45","%H:%i") AND TIME_FORMAT("23:59","%H:%i") 
               OR ZSP.heure BETWEEN TIME_FORMAT("00:00","%H:%i") AND TIME_FORMAT("11:45","%H:%i")) 
    ORDER BY 
        ZSP.heure ASC

    Ma requête fonctionne bien sans la clause not exists et la requête de la clause not exists fonctionne bien lorsque je la lance indépendamment de la première.
    Mais lorsque je lance les deux requêtes ensemble, j'obtiens un résultat vide. Pourquoi?

  2. #2
    Membre éclairé Avatar de bstevy
    Homme Profil pro
    Solutions Architect
    Inscrit en
    Mai 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Japon

    Informations professionnelles :
    Activité : Solutions Architect
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2009
    Messages : 552
    Points : 870
    Points
    870
    Par défaut
    Le where va filter les lignes que tu ramènes, donc si tu match par avec zs_historique, tu ne ramène que des colonnes null qu'apres tu mets dans un where exist qui te filtre le tout.

    Si tu veux que ton exist soit inclu dans le where, il faut le mettre au niveau de la jointure.

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2013
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Novembre 2013
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    L'inclure dans la jointure? Je ne suis pas sur de comprendre.
    Il faut faire quelque chose comme :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    ...
    LEFT JOIN 
        zs_historique ZSH 
        ON ZSPT.id_prevision = ZSH.id_prevision  
     
        NOT EXISTS (SELECT  .id_prevision 
                           FROM ZSH  
                           LEFT JOIN zs_prevision ON zs_prevision.id_prevision = zs_historique.id_historique 
                           WHERE (date = DATE_FORMAT('23/8/2015','%d/%m/%Y')
                                          and zs_prevision.heure > TIME_FORMAT('22:45','%H:%i'))
                                      OR(date = CURDATE())) 
    WHERE 
    ...

  4. #4
    Membre averti
    Homme Profil pro
    Ingénieur en études décisionnelles
    Inscrit en
    Février 2013
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur en études décisionnelles

    Informations forums :
    Inscription : Février 2013
    Messages : 134
    Points : 351
    Points
    351
    Par défaut
    C'est l'idée, rajoute un "and" juste avant le not exists et ça devrait être bon.
    C'est quelque chose de récurrent avec les jointures externes

  5. #5
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    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 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Il y a peut-être une confusion aussi entre "NOT EXISTS" et "NOT IN".

    En effet, dans votre "NOT EXISTS", vous ramenez la liste des ID qui à priori doivent être écartés. Je verrais donc plutôt un "prevision_id not in (select prevision_id from ...)"

    En effet, le "NOT EXISTS" ne porte pas spécifiquement sur une colonne (on utilise généralement une constante (null ou 1) dans le SELECT) afin d'éviter la confusion à la relecture.

    Et cela permet de filtrer les lignes qui ne respectent pas une clause de filtre.

    Par exemple, mettons la table "produit" et la table "commande".

    On veut afficher la liste des produits qui n'ont pas été commandés :

    Avec NOT IN :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select *
    from produit
    where produit.id not in (select commande.produit_id from commande)

    Avec NOT EXISTS :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select *
    from produit
    where not exists (select null from commande inner join produit on produit.id = commande.produit_id)

    Pour un résultat identique, on voit que les conditions ne sont pas les mêmes.

    Moi j'ai l'impression que vous tentez d'utiliser la syntaxe du NOT EXISTS avec une condition NOT IN.

    Accessoirement, je trouve qu'il y a un peu trop d'éléments à mon goût dans votre FROM de la sous-requête.
    Ne voulez-vous pas utiliser les tables déjà présentes dans la requête principale à la place ?
    On ne jouit bien que de ce qu’on partage.

Discussions similaires

  1. Problème pour la Division avec NOT EXISTS
    Par myzu69 dans le forum Langage SQL
    Réponses: 1
    Dernier message: 08/11/2007, 14h50
  2. [SQL Server] Probleme avec not exists
    Par maxxou dans le forum Langage SQL
    Réponses: 2
    Dernier message: 16/03/2006, 16h51
  3. problème avec if Exist
    Par flo456 dans le forum ASP
    Réponses: 4
    Dernier message: 15/03/2006, 10h59
  4. [PHPMyAdmin]Problème avec "Not Null" dans mysql 5
    Par Ryan Sheckler dans le forum Requêtes
    Réponses: 4
    Dernier message: 15/12/2005, 14h45
  5. Requète avec NOT EXISTS
    Par missllyss dans le forum SQL
    Réponses: 2
    Dernier message: 23/09/2003, 15h20

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