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 :

Probleme clause NOT EXISTS et NOT IN


Sujet :

Langage SQL

  1. #1
    Membre du Club
    Inscrit en
    Janvier 2006
    Messages
    137
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 137
    Points : 62
    Points
    62
    Par défaut Probleme clause NOT EXISTS et NOT IN
    Bonjour,

    Je reviens sur le forum pour avoir un peu d'aide. J'ai un petit problème avec ma requête sql avec laquelle j'utilise comme contrainte NOT EXISTS ou not in.

    En fait, j'ai une table contenant toutes les valeurs (table Stock) et une autre table contenant une partie des valeurs (table Stock2) de la précédente table. Mon but est d'afficher toutes les valeurs qui ne sont pas contenues dans la seconde table Stock2. En gros, je voudrais afficher tous les libellés = 'lost' qui ne sont pas dans Stock2 et qui ont donc un numéro différent de Stock.

    Table Stock
    Libelle | numero
    lost | 1
    lost | 30
    toto | 2
    lost | 30
    alpha |19
    alpha | 20
    lost | 15

    Table Stock2
    Libelle | numero
    lost | 1
    lost | 25
    alpha | 19

    J'ai essayé de faire ça plusieurs façons mais sans succés:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT  *
    FROM Stock
    WHERE  
    Stock.[numero]=
    NOT EXISTS
    (SELECT distinct *  
    FROM T_Stock
    );
    Ca me retourne rien

    de même si je rajoute le libellé comme contrainte supplémentaire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    select distinct * from Stock
    where
    Stock.[libelle] = 'lost' and
    Stock.numero = 
    not exists 
    (select distinct * from Stock2 where Stock2.[libelle]='lost');
    J'ai essayé avec la clause not in :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT * from Stock
    WHERE
    Stock.libelle = 'lost' 
    AND 
    Stock.numero
    NOT IN
    (
    SELECT Stock2.numero from Stock2 where Stock2.libelle = 'lost');
    avec cette dernière ça me sort une liste abominable et qui est fausse .

    Si quelqu'un peut m'aider.
    Merci.

  2. #2
    Membre éprouvé Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Points : 1 107
    Points
    1 107
    Par défaut
    Bonjour,

    L'opérateur EXISTS s'utilise principalement avec une sous-requête corrélée, comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT libelle, numero
    FROM Stock
    WHERE libelle = 'lost'
    AND NOT EXISTS (
      SELECT *
      FROM Stock2
      WHERE Stock.libelle <> Stock2.libelle
        AND Stock.numero <> Stock2.numero
    )
    Une requête équivalente avec IN:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT libelle, numero
    FROM Stock
    WHERE libelle = 'lost'
    AND (libelle, numero) NOT IN (
      SELECT libelle, numero
      FROM Stock2
    )

  3. #3
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 006
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 006
    Points : 30 944
    Points
    30 944
    Billets dans le blog
    16
    Par défaut
    Citation Envoyé par Jarod51
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT * FROM Stock
    WHERE
    Stock.libelle = 'lost' 
    AND 
    Stock.numero
    NOT IN
    (
    SELECT Stock2.numero FROM Stock2 WHERE Stock2.libelle = 'lost');
    avec cette dernière ça me sort une liste abominable et qui est fausse
    Votre requête est correcte puisqu'elle fournit les lignes de la table Stock qui sont absentes de la table Stock2. Ajoutez un DISTINCT, car votre table Stock contient des doublons (c'est donc plus un sac qu'une table). Pourriez-vous montrer la liste abominable, ou à tout le moins dire pourquoi elle est abominable ?


    Citation Envoyé par Jarod51
    En fait, j'ai une table contenant toutes les valeurs (table Stock) et une autre table contenant une partie des valeurs (table Stock2) de la précédente table
    Attention, la table Stock2 que vous nous proposez contient des valeurs absentes de la table Stock ('lost', 25).
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  4. #4
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 006
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 006
    Points : 30 944
    Points
    30 944
    Billets dans le blog
    16
    Par défaut
    Citation Envoyé par Oishiiii

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT libelle, numero
    FROM Stock
    WHERE libelle = 'lost'
    AND NOT EXISTS (
      SELECT *
      FROM Stock2
      WHERE Stock.libelle <> Stock2.libelle
        AND Stock.numero <> Stock2.numero
    )
    Remplacer l'opérateur '<>' par l'opérateur '='... :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT libelle, numero
    FROM Stock
    WHERE libelle = 'lost'
    AND NOT EXISTS (
      SELECT *
      FROM Stock2
      WHERE Stock.libelle = Stock2.libelle
        AND Stock.numero = Stock2.numero
    )
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  5. #5
    Membre du Club
    Inscrit en
    Janvier 2006
    Messages
    137
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 137
    Points : 62
    Points
    62
    Par défaut
    Bonjour,

    Merci pour vos réponses. La seconde requête de Oishiiii :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT libelle, numero
    FROM Stock
    WHERE libelle = 'lost'
    AND (libelle, numero) NOT IN (
      SELECT libelle, numero
      FROM Stock2
    )
    Ne me renvoit pas de résultats. Peut être parce que je suis sous ACCESS. j'ai essayé la solution que me propose fsmrel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT libelle, numero
    FROM Stock
    WHERE libelle = 'lost'
    AND NOT EXISTS (
      SELECT *
      FROM Stock2
      WHERE Stock.libelle = Stock2.libelle
        AND Stock.numero = Stock2.numero
    )
    Par contre, avec la requête que vous m'avez écrite, est il possible de rajouter une 3ème table Stock3 qui contient elle aussi une partie des valeurs de la table Stock ?

    j'ai essayé de faire quelques choses de ce genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT libelle, numero
    FROM Stock
    WHERE libelle = 'lost'
    AND NOT EXISTS (
      SELECT *
      FROM Stock2, Stock3
      WHERE Stock.libelle = Stock2.libelle
        AND Stock.numero = Stock2.numero
        AND Stock.numero = Stock3.numero
        AND Stock.libelle = Stock3.libelle
    )
    Le résultat retourné est me parait faux.

    Le problème est que, en fait, dans Stock j'ai 1846 ressources 'lost', 1454 ressources 'lost' dans Stock2 identiques à Stock et 44 ressources 'lost' dans Stock3 identique à Stock. Donc, je devrais arrivé à extraire de Stock 378 ressources 'lost' de la table Stock qui ne sont ni dans Stock2 ni dans Stock3. En appliquant, la requete sql, j'arrive à 1848 ressources ce qui fort differents de 378

    Comment faire ??

  6. #6
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 006
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 006
    Points : 30 944
    Points
    30 944
    Billets dans le blog
    16
    Par défaut
    Comment faire ??
    Procéder à l'union des résultats correspondant à Sock2 et Stock3 :

    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
    SELECT DISTINCT libelle, numero, 'Stock2'
    FROM Stock
    WHERE libelle = 'lost'
    AND NOT EXISTS (
      SELECT *
      FROM Stock2
      WHERE Stock.libelle = Stock2.libelle
        AND Stock.numero = Stock2.numero)
    UNION 
    SELECT libelle, numero, 'Stock3'
    FROM Stock
    WHERE libelle = 'lost'
    AND NOT EXISTS (
      SELECT *
      FROM Stock3
      WHERE Stock.libelle = Stock3.libelle
        AND Stock.numero = Stock3.numero)
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  7. #7
    Membre expérimenté Avatar de Yanika_bzh
    Homme Profil pro
    Responsable Applicatif et R&D
    Inscrit en
    Février 2006
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Responsable Applicatif et R&D
    Secteur : Finance

    Informations forums :
    Inscription : Février 2006
    Messages : 1 144
    Points : 1 738
    Points
    1 738
    Par défaut
    Je ne sais pas si j'ai bien compris votre probleme, mais est ce qu'une requete de ce type ne peut pas vous aider ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select a.* 
      from Stock a left outer join Stock2 b on (a.libelle=b.libelle and a.numero=b.numero)
    where b.numero is null and a.libelle <>'lost'
    Bon Courage
    Dans la connaissance du monde, ceux qui ne savent rien en savent toujours autant que ceux qui n'en savent pas plus qu'eux. (Pierre Dac)

  8. #8
    Membre du Club
    Inscrit en
    Janvier 2006
    Messages
    137
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 137
    Points : 62
    Points
    62
    Par défaut
    Salut,

    oui merci pour la réponse. J'ai essayé la méthode avec union mais ça ne marche pas avec ACCESS.

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 31/07/2009, 21h43
  2. AS400 Probleme de Create table if not exists
    Par mczikas dans le forum Développement de jobs
    Réponses: 0
    Dernier message: 24/02/2009, 17h04
  3. [9i] Not in ou not exists
    Par billout9 dans le forum SQL
    Réponses: 9
    Dernier message: 30/10/2007, 09h36
  4. Réponses: 10
    Dernier message: 14/12/2006, 12h53
  5. Utilisation de EXISTS ou NOT EXISTS
    Par lucky31 dans le forum Langage SQL
    Réponses: 4
    Dernier message: 31/05/2006, 16h43

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