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 :

Alternative à NOT IN


Sujet :

Langage SQL

  1. #1
    Candidat au Club
    Alternative à NOT IN
    Bonjour,

    Je débute sur SQL, et je cherche une alternative a NOT IN.
    A titre d'exemple, j'ai deux tables Clients et Banque

    Table Clients
    id name
    1 Nom1
    2 Nom2
    3 Nom3
    4 Nom4

    Table Banque
    id event Payout_id
    1 Event1 3
    2 Event2 2
    3 Nom3 5
    4 Nom4 null


    Est-ce qu'il est possible d'utiliser deux valeurs de tables differentes id et payout_id comme ce code la ?
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    SELECT * from Client where id NOT IN (SELECT payout_id from Banque)


    Existe t-il une autre solution pour ne pas utiliser NOT IN ?

    Merci beaucoup et bonne journée !

  2. #2
    Expert éminent sénior
    Bonjour,

    Autrefois, NOT EXISTS était beaucoup plus performant que NOT IN , ce n'est plus toujours vrai de nos jours l'optimiseur sait traduire le NOT IN en NOT EXISTS.
    À tester au cas où votre version de SGBD serait un peu dépassée

    Ce qui donne :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    select CL.col1
         , CL.col2
         , ...
         , CL.coln
    from client as CL
    where not exists
         (select 1
          from banque as BQ
          where BQ.payout_id = CL.id
         )

  3. #3
    Modérateur

    Deux alternatives :
    1. Avec NOT EXISTS
      Code :Sélectionner tout -Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      SELECT  * 
      FROM    Client  clt 
      WHERE   NOT EXISTS 
              (   SELECT  payout_id 
                  FROM    Banque  bnq
                  WHERE   bnq.payout_id = clt.id
              )
      ;
    2. Avec LEFT JOIN ... WHERE ... IS NULL
      Code :Sélectionner tout -Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      SELECT  * 
      FROM    Client  clt
          LEFT JOIN
              Banque  bnq
              ON  bnq.payout_id = clt.id
      WHERE   bnq.id  IS NULL
      ;
    Cette signature n'a pas pu être affichée car elle comporte des erreurs.

  4. #4
    Expert éminent sénior
    Citation Envoyé par al1_24 Voir le message
    Deux alternatives :
    • Avec LEFT JOIN ... WHERE ... IS NULL
    Attention pour cette solution à bien vérifier qu'il s'agit d'une colonne NOT NULL qui ne peut donc être "null" que si la jointure outer n'est pas satisfaite

  5. #5
    Modérateur

    En effet, j'aurais du préciser WHERE tb2.pk IS NULL.
    Cette signature n'a pas pu être affichée car elle comporte des erreurs.

  6. #6
    Candidat au Club
    He bien ! Merci pour ces réponses rapides ! Vous m'avez bien aidé !! C'est exactement ce que je cherchais.

    Bonne journée !

  7. #7
    Expert éminent
    Bonjour, en DB2/AS400 (je ne sais pas si c'est possible sur MAINFRAME) on peut utiliser l'exception join qui est très élégant je trouve. Ce qui dans le cas présent donnerait :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT cli.* from Client cli 
    exception join Banque bq on 
    bq.payout_id= cl.id

  8. #8
    Membre expert
    Citation Envoyé par al1_24 Voir le message
    Deux alternatives :
    + la technique du MINUS qui peut être efficace ici car PK et probablement FK sont utilisées
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    SELECT  * 
    FROM    Client  clt 
    WHERE   id IN 
    (   
    SELECT id FROM Client
    MINUS
    SELECT payout_id FROM Banque  
    )

    Comparez les plans avant de choisir.

  9. #9
    Expert éminent sénior
    Bonjour,
    Citation Envoyé par Darkzinus Voir le message
    Bonjour, en DB2/AS400 (je ne sais pas si c'est possible sur MAINFRAME) on peut utiliser l'exception join qui est très élégant je trouve. Ce qui dans le cas présent donnerait :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT cli.* from Client cli 
    exception join Banque bq on 
    bq.payout_id= cl.id
    C'est une spécificité DB2/400 (DB2 for system i)



    Citation Envoyé par JeitEmgie Voir le message
    + la technique du MINUS qui peut être efficace ici car PK et probablement FK sont utilisées
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    SELECT  * 
    FROM    Client  clt 
    WHERE   id IN 
    (   
    SELECT id FROM Client
    MINUS
    SELECT payout_id FROM Banque  
    )

    MINUS ou EXCEPT selon les SGBD

###raw>template_hook.ano_emploi###