requete sql select... where... NOT in ...

requete sql select... where... NOT in ... - SQL/NoSQL - Programmation

Marsh Posté le 04-01-2012 à 18:32:58    

Bonsoir
 
je fais une requete sql sous acces ou je veux trouver les produits en stock non existant dans un fichier d'article
 
voila la requete que j'ai ecrite
 
SELECT stock2.Code_alpha, stock2.[date-saisie], stock2.quantité
FROM stock2
WHERE (stock2.[Code_alpha] not   in
 ( SELECT article_base.Code_alpha
FROM article_base;)  );
 
La requete ... IN    remonte 5287 enreg  sur les 5575 du fichier stock
 et la requete NOT in    remonte 0 !!!
 
 
Qui peux m'aider ou me donner une piste  
 
MERCI d'avance


---------------
PASCAL DE STRASBOURG
Reply

Marsh Posté le 04-01-2012 à 18:32:58   

Reply

Marsh Posté le 04-01-2012 à 18:40:44    

not exists plutot si il n'existent pas

 

edit ou mieux
SELECT stock2.Code_alpha, stock2.[date-saisie], stock2.quantité
from stock2 left join article_base on article_base.Code_alpha  = stock2.[Code_alpha]
WHERE  article_base.Code_alpha IS NULL
ce sera largement plus performant


Message édité par flo850 le 04-01-2012 à 18:44:15
Reply

Marsh Posté le 04-01-2012 à 18:46:23    

Si "in" remonte 5287 enregistrements "not in" devrait en remonter  5575 - 5287. C'est bizzare.  :heink:
 
<troll>
Essai avec un vrai SGDBR tel que MySQL ou PostgreSQL et pas cette contrefaçon qu'est Access. :p
</troll>
 
PS: Dsl pour le troll c'était plus fort que moi.

Reply

Marsh Posté le 04-01-2012 à 20:10:12    

j'avais meme pas vu qeu c'etait du access :vomi:

Reply

Marsh Posté le 05-01-2012 à 08:50:20    

SELECT stock2.Code_alpha, stock2.[date-saisie], stock2.quantité
FROM stock2 a
LEFT JOIN article_base b on b.Code_alpha = a.Code_alpha
WHERE b.Code_alpha is null

Reply

Marsh Posté le 05-01-2012 à 11:19:59    

flo850 a écrit :

j'avais meme pas vu qeu c'etait du access :vomi:


C'est sûr qu'on peut difficilement assimiler Access à un SGBD :/


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 24-01-2012 à 14:09:04    

spamoa a écrit :

Si "in" remonte 5287 enregistrements "not in" devrait en remonter  5575 - 5287. C'est bizzare.  :heink:
 
<troll>
Essai avec un vrai SGDBR tel que MySQL ou PostgreSQL et pas cette contrefaçon qu'est Access. :p
</troll>
 
PS: Dsl pour le troll c'était plus fort que moi.


 
Pas forcement, (null) n'est pas traité de la même façon dans tout les SGBD.


---------------
| AMD Ryzen 7 7700X 8C/16T @ 4.5-5.4GHz - 64GB DDR5-6000 30-40-40 1T - AMD Radeon RX 7900 XTX 24GB @ 2680MHz/20Gbps |
Reply

Marsh Posté le 24-01-2012 à 14:19:43    

Oliiii a écrit :

SELECT stock2.Code_alpha, stock2.[date-saisie], stock2.quantité
FROM stock2 a
LEFT JOIN article_base b on b.Code_alpha = a.Code_alpha
WHERE b.Code_alpha is null


Ca me faire bizarre la left join avec un is null sur la condition de jointure... :??:
 
 
A tester, basé sur sa version de la requête :

Code :
  1. SELECT
  2.    stock2.Code_alpha,
  3.    stock2.[date-saisie],
  4.    stock2.quantité
  5. FROM
  6.    stock2
  7. WHERE
  8.    stock2.[Code_alpha] NOT IN (
  9.        SELECT
  10.            article_base.Code_alpha
  11.        FROM article_base
  12.    ) OR
  13.   stock2.[Code_alpha) IS NULL
  14. ;


 
Sinon plus simple, je dirais :

Code :
  1. SELECT
  2.    stock2.Code_alpha,
  3.    stock2.[date-saisie],
  4.    stock2.quantité
  5. FROM
  6.    stock2
  7. WHERE
  8.    NOT EXISTS (
  9.        SELECT
  10.            1
  11.        FROM
  12.            article_base
  13.        WHERE
  14.            article_base.[Code_alpha] = stock2.[Code_alpha]
  15.    )
  16. ;


 
Et pour modérer ce que disais Flo850, on s'en fou de faire une requête toute belle plein de jointure ou non, le but c'est d'avoir du SQL compréhensible à la lecture, et les optimisations des SGBD vont (quasi-toujours) convertir les in en where et les exists en jointure d'eux-même. :spamafote:


---------------
| AMD Ryzen 7 7700X 8C/16T @ 4.5-5.4GHz - 64GB DDR5-6000 30-40-40 1T - AMD Radeon RX 7900 XTX 24GB @ 2680MHz/20Gbps |
Reply

Marsh Posté le 25-01-2012 à 10:07:56    

Les JOIN sont le standard et probablement toujours plus lisible que l'equivalent utilisant un sous select.
L'optimisateur arrive a la meme conclusion dans les deux cas mais ce n'est pas forcement garantis pour tout les SGBD.
Optimiser une query avec un sous select a la place d'un join prends un peut plus de temps aussi, et des fois ca fait la difference entre un bon query plan et un mauvais.
 
En regle generale il faut eviter les not exists et les not in, ca ouvre la porte a pleins de problemes si on ne fais attention.
 
La "beauté" du code a son importance, une requete avec un JOIN (ou left join + is null) est toujours plus compacte, et donc plus lisible qu'une query de 2km de long (15lignes vs 4 quand meme).
Des fois avoir un code compact (sans exagerer) est bien plus pratique que d'avoir de l'indentation et des retour a la ligne intempestif.
 
Au passage désolé a flo850 d'avoir repondu la meme chose que toi, j'avais pas vu que t'avais déja repondu ca :)

Reply

Marsh Posté le 25-01-2012 à 10:27:56    

Ce n'est pas parce que c'est le "standard" (ouai à voir ce qu'on appelle le standard) que c'est plus compéhensible.
 
C'est quand même plus naturel à la compréhension de lire une requête avec des in/exists qui on plus de sémantique que des simple join. (et là on reste dans le SQL standard, si tu sort du SQL avec les jointures proprio Oracle c'est carrément à gerber...)

Message cité 1 fois
Message édité par MEI le 25-01-2012 à 10:30:29

---------------
| AMD Ryzen 7 7700X 8C/16T @ 4.5-5.4GHz - 64GB DDR5-6000 30-40-40 1T - AMD Radeon RX 7900 XTX 24GB @ 2680MHz/20Gbps |
Reply

Marsh Posté le 25-01-2012 à 10:27:56   

Reply

Marsh Posté le 25-01-2012 à 10:31:09    

perso, je préfère largement les jointures
je trouve ça plus lisible

Reply

Marsh Posté le 25-01-2012 à 10:47:28    

flo850 a écrit :

perso, je préfère largement les jointures
je trouve ça plus lisible


Sauf que sémantiquement c'est plus difficile de comprendre ce qu'il va se passer, et qu'en plus en fait en pratique ça peut être moins perfs :
http://explainextended.com/2009/09 [...] ql-server/
 
EDIT : De ce que j'ai lu, c'est le comportement décris est aussi valable pour Oracle.


Message édité par MEI le 25-01-2012 à 10:48:31

---------------
| AMD Ryzen 7 7700X 8C/16T @ 4.5-5.4GHz - 64GB DDR5-6000 30-40-40 1T - AMD Radeon RX 7900 XTX 24GB @ 2680MHz/20Gbps |
Reply

Marsh Posté le 25-01-2012 à 10:58:56    

Je cherche à associer tous mes élements de ma table gauche à ceux qui correspondent dans ma table  de droite (en utilisant telle et telle colonne pour faire le rapprochement )  
 
et en fait, je veux ceux qui n'ont rien à droite
 
Ca me semble plutôt compréhensible

Reply

Marsh Posté le 26-01-2012 à 08:50:13    

MEI a écrit :

Ce n'est pas parce que c'est le "standard" (ouai à voir ce qu'on appelle le standard) que c'est plus compéhensible.
 
C'est quand même plus naturel à la compréhension de lire une requête avec des in/exists qui on plus de sémantique que des simple join. (et là on reste dans le SQL standard, si tu sort du SQL avec les jointures proprio Oracle c'est carrément à gerber...)


 
C'est peut etre moins comprehensible pour toi, ca depend de l'habitude que tu as avec SQL. Perso je fais du SQL toute la journée et le temps de comprehension d'une query depend uniquement de la taille, donc plus c'est petit (sans etre compacté a outrance), plus c'est facil a comprendre et a lire.
Ce n'est peut etre pas evident avec des petites queries, mais des que tu as plusieurs tables ou tu dois melanger les JOIN et LEFT JOIN pour inclure et exclure des resultats ca devient tres tres vite illisible avec des NOT IN ou NOT EXISTS, surtout si on dois modifier une query existante pour juste enlever certains resultats (table d'exception, etc ...), on ajoute 2 lignes max avec un LEFT JOIN/ IS NULL.
Ca fait aussi une difference enorme pour la maintenance, en general tout est sur la meme ligne que le LEFT JOIN, il n'y a pas de parentese partout, pas plusieurs fois le mot select ni le mot where. Dans les grosses query ca fait la difference entre une query ou on en arrive a se perdre et une query qui tient sur 10 lignes et qui est comprehensible en un coup d'oeuil.
 
La question des perfs est tout a fait valide, mais comme pour toute question de perf ce n'est a utiliser que dans les cas ou c'est utile.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed