2016-10-27 4 views
-2

J'ai besoin d'aide pour une requête SQL. J'ai une "table de liste principale (catégories X et Y)". Je dois comparer la liste ci-dessus avec deux tables de liste Sous - « Liste X » et « Liste Y »Identifiants exclusifs SQL Select comparant la liste principale à deux sous-listes

Tables:

*MasterList*    
ID Cat Status   
101 X Ready    
102 X Ready    
103 Y Dispatched Y  
104 X Dispatched Y  
105 Y Dispatched  
106 X Ready 
107 X Dispatched Y 
108 Y Ready Y 
109 X Dispatched 
110 Y Dispatched 
111 X Ready Y 
112 X Dispatched 
113 X Dispatched Y 

*ListX* 
ID  
101 
102 
106 
109 
112 

*ListY* 
ID 
105 
110 

Je suis en train de créer une requête qui produit:

  1. ID Cat-X qui ne sont pas disponibles dans la liste X
  2. ID Cat-Y qui ne sont pas disponibles dans la liste Y-

Sortie

ID Cat Status 
103 Y Dispatched 
104 X Dispatched 
107 X Dispatched 
108 Y Ready 
111 X Ready 
113 X Dispatched 

Merci,

Ravi.

+0

Oracle ou mysql? Aussi, s'il vous plaît poster quelques exemples de données (texte formaté), le résultat nécessaire et ce que vous avez essayé jusqu'à présent – Aleksej

+0

Merci Strawberry, j'essaie de faire la même chose :) – Ravi

Répondre

0

Vous pouvez le faire de plusieurs façons, par exemple comme ici:

select * 
    from master_list 
    where (cat = 'X' and id not in (select id from listx)) 
    or (cat = 'Y' and id not in (select id from listy)) 

Essayez aussi not exists et simple joint.


données de test dans Oracle et de sortie:

create table master_list (id int, cat varchar2(1), status varchar2(15)); 
insert into master_list values (101, 'X', 'Ready'); 
insert into master_list values (102, 'X', 'Ready'); 
insert into master_list values (103, 'Y', 'Dispatched'); 
insert into master_list values (104, 'X', 'Dispatched'); 
insert into master_list values (105, 'Y', 'Dispatched'); 
insert into master_list values (106, 'X', 'Ready'); 
insert into master_list values (107, 'X', 'Dispatched'); 
insert into master_list values (108, 'Y', 'Ready'); 
insert into master_list values (109, 'X', 'Dispatched'); 
insert into master_list values (110, 'Y', 'Dispatched'); 
insert into master_list values (111, 'X', 'Ready'); 
insert into master_list values (112, 'X', 'Dispatched'); 
insert into master_list values (113, 'X', 'Dispatched'); 

create table listx as (select column_value id 
         from table(sys.odcinumberlist(101, 102, 106, 109, 112))); 
create table listy as (select column_value id 
         from table(sys.odcinumberlist(105, 110))); 

    ID CAT STATUS 
---- --- --------------- 
103 Y Dispatched 
104 X Dispatched 
107 X Dispatched 
108 Y Ready 
111 X Ready 
113 X Dispatched 
+0

Ponder, cela a fonctionné parfait pour moi. Puis-je utiliser la même chose même si l'ID de comparaison est une chaîne? – Ravi

+0

Oui. Je ne pense pas que ce type de colonne devrait avoir de l'importance, à moins qu'ils ne soient identiques dans toutes les tables. Il est toujours bon de mettre ces informations en question principale. –

+0

Merci Ponder. J'ai essayé ça aussi. Juste pour confirmer afin que je puisse l'utiliser à l'avenir :) – Ravi

0

Vous pouvez utiliser un OU dans la clause WHERE:

SELECT ID, CAT, STATUS 
    FROM MASTERLIST M 
WHERE (M.ID NOT IN (SELECT ID FROM LISTX) AND CAT = 'X') 
    OR (M.ID NOT IN (SELECT ID FROM LISTY) AND CAT = 'Y'); 

Autre alternative serait de séparer les règles en deux querys et combiner ensuite avec UNION ALL:

SELECT ID, CAT, STATUS 
    FROM MASTERLIST M 
WHERE M.ID NOT IN (SELECT ID FROM LISTX) AND CAT = 'X' 
UNION ALL 
SELECT ID, CAT, STATUS 
    FROM MASTERLIST M 
WHERE M.ID NOT IN (SELECT ID FROM LISTY) AND CAT = 'Y'; 

Les deux techniques conduiront aux mêmes résultats. En fait, certains optimiseurs (comme Oracle) vont essayer de convertir la première solution en la seconde en temps réel. C'est ce qu'on appelle une expansion OR.