Afficher des valeurs qui ne sont pas dans un groupe

Afficher des valeurs qui ne sont pas dans un groupe - SQL/NoSQL - Programmation

Marsh Posté le 17-06-2010 à 17:17:46    

Bonjour à tous,
 
J'ai un problème que je n'arrive pas à résoudre en sql sous access. J'ai une table qui se structure de la façon suivante :
 
Table Stock :
Type | numero |
----------------
DNA  | 30        |
Lym  | 30        |
DNA  | 10        |
Lym  | 15        |
DNA  | 40        |
Lym  | 40        |
DNA  | 19        |  
Lym  | 20        |
 
En fait, les valeurs {DNA, Lym} qui ont le même numéro forme un groupe. Ce que je voudrais faire c'est afficher tous les DNA qui ont un numéro différent du Lym.
 
J'ai essayé deux choses, la première :
 

Code :
  1. SELECT *
  2. from Stock
  3. where
  4. Stock.[Type] = 'DNA'
  5. and Stock.numero <> T_Stock.numero;


 
En gros ça me retourne rien.
 
Du coup, j'ai copié toutes les valeurs DNA de la table Stock dans une autre table que j'ai nommé Stock_temp. Ensuite, j'ai essayé la chose suivante :
 

Code :
  1. SELECT *
  2. FROM Stock, Stock_temp
  3. WHERE T_Stock.numero not like Stock_temp.numero
  4. AND Stock.[Type]='DNA';


 
Ca me retourne une liste énorme qui est incorrecte. Est ce que quelqu'un pourrait m'aider, svp ?
 
Merci.

Reply

Marsh Posté le 17-06-2010 à 17:17:46   

Reply

Marsh Posté le 17-06-2010 à 18:35:08    

Je propose:

SELECT *
FROM Stock
WHERE Stock.Type='DNA'  
AND Stock.numero NOT IN ( SELECT numero
     FROM Stock
     WHERE Stock.Type='Lym');


---------------
C'était vraiment très intéressant.
Reply

Marsh Posté le 18-06-2010 à 07:49:37    

Il y a ca aussi:
 

Code :
  1. SELECT a.*
  2. FROM Stock a
  3.     LEFT JOIN Stock b ON a.numero = b.numero AND b.Type = 'Lym'
  4. WHERE a.Type = 'DNA'
  5.     AND b.Type IS NULL

Reply

Marsh Posté le 18-06-2010 à 08:35:28    

J'en profile pour rappeler l'importance d'utiliser les Join.
Si la query tourne sur une petite table de 8 records ca ne change rien, mais j'ai fais le test sur un table de 10Mil rows:

Code :
  1. SELECT a.*
  2. FROM Stock a
  3.     LEFT JOIN Stock b ON a.numero = b.numero AND b.Type = 'Lym'
  4. WHERE a.Type = 'DNA'
  5.     AND b.Type IS NULL
  6.  
  7. /*
  8. Table 'Stock'. Scan count 10, logical reads 39528, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
  9. Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
  10.  
  11. SQL Server Execution Times:
  12.   CPU time = 12828 ms,  elapsed time = 8887 ms.
  13. */


Code :
  1. SELECT *
  2. FROM Stock
  3. WHERE Stock.Type='DNA'  
  4. AND Stock.numero NOT IN ( SELECT numero
  5.     FROM Stock
  6.     WHERE Stock.Type='Lym');
  7.  
  8. /*
  9. Table 'Stock'. Scan count 18, logical reads 10118584, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
  10. Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
  11. Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
  12.  
  13. SQL Server Execution Times:
  14.   CPU time = 4299639 ms,  elapsed time = 1174512 ms.
  15. */


 
On passe de 12sec a 20mins (sur un quad core)

Reply

Marsh Posté le 18-06-2010 à 10:34:08    

Tiens ca c'est intéressant, en plus j'avoue que j'avais jamais pensé à utiliser une comparaison directe à une constante directement dans un join. La requete est moins intuitive mais effectivement j'comprends pourquoi ca va beaucoup plus vite (de toute facons si j'me souviens bien, IN et NOT IN c'est genre LE truc à éviter). Merci pour le "truc".


---------------
C'était vraiment très intéressant.
Reply

Marsh Posté le 18-06-2010 à 19:33:52    

Si la modélisation est bien concue et performante (index, pk ...), je ne vois pas pourquoi un IN et NOT IN est à éviter ... Cela fonctionne très bien

Reply

Marsh Posté le 18-06-2010 à 23:20:41    

Le DBA de mon ancien job: "IN faut éviter, utilises un truc avec EXISTS plutot".
Le DBA de mon job actuel: "IN c'est pas bien, évites ca si t'as beaucoup de donées en jeu".
Et en plus il y a une limite de taille pour le second opérateur du IN, et je l'ai déjà tapée en situation réelle.
Donc j'dis pas que c'est forcément vrai, mais bon deux DBA qui me disent d'éviter, je les crois et je cherche pas trop à approfondir (ils sont OCP tous les deux).


---------------
C'était vraiment très intéressant.
Reply

Marsh Posté le 19-06-2010 à 16:39:56    

Salut à tous
Merci beaucoup pour vos réponses. Je ne pensais pas que les Join ont un tel importance dans le temps d'exécution d'une requête. Je me suis donc orienter vers la méthode d'Oliii car mes tables contiennent beaucoup de données.
 
En tout cas je vous remercie à tous pour votre aide et les explications. Super  :)  
 
A+

Reply

Sujets relatifs:

Leave a Replay

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