2010-02-12 33 views
5

Recentemente ho visto qualcuno posta questo come parte di una risposta ad una domanda SO query:Puoi usare più colonne per una non nella query?

SELECT DISTINCT a, b, c 
FROM t1 
WHERE (a,b,c) NOT IN 
    (SELECT DISTINCT a,b,c FROM t2) 

Sono un po 'confuso, come ho sempre pensato che non è possibile utilizzare più colonne per "NOT IN" ("dove (a, b, c)", ecc.). Questa sintassi SQL è corretta? E che dire di MySQL?

risposta

3

E 'un'estensione di SQL. Oracle, PostgreSQL e MySQL ce l'hanno. SQL Server 2005 non ce l'ha. Non sono sicuro degli altri.

+0

Oracle lo ha anche –

0

Non che io sappia, ma se thy're tipo di carattere (o può essere convertito a char tipi), è possibile fingere:

SELECT DISTINCT a, b, c 
FROM t1 
WHERE a+b+c NOT IN 
    (SELECT DISTINCT a+b+c FROM t2) 
+0

Questo ha un bug in esso. a = 'ab' b = 'cd' c = 'ef' corrisponderà con a = 'abcd' b = 'e' c = 'f' ... –

+0

Dovresti stare attento ad assicurarti di non indossare t ottenere collisioni basate sul contenuto della colonna. Inserisco i separatori in modo che le colonne non vengano eseguite accidentalmente con conseguente falsi positivi: 'a' + 'bb' + 'c "==' ab '+' b '+' c ' – tvanfosson

+0

Non funziona per certe stringhe però ... a + b potrebbe essere "abc" per a = "ab" e b = "c", o a = "a" eb = "bc". – Corey

0

Prova questa

SELECT DISTINCT a, b, c 
FROM t1, 
(SELECT DISTINCT a,b,c FROM t2) as tt 
WHERE t1.a NOT IN tt.a 
AND t1.b NOT IN tt.b 
AND t1.c NOT IN tt.c 

Nota: Questo non è stato testato ma non e 'nemmeno stata dimostrata corretta.

+0

La mia domanda non è come farlo - ne so di un paio di modi. so se la sintassi è corretta, come qualcuno lo ha postato e nessuno ha obiettato – froadie

+0

@froadie Perdonami, incomprensione.Altre persone hanno risposto correttamente alla tua domanda.Vedo –

1

Certamente funziona in Oracle. Breve esempio inventato:

SQL> select ename, job, deptno from emp 
    2 where (ename, deptno) in 
    3 (select ename, deptno from emp 
    4 where job = 'MANAGER' 
    5 ); 

ENAME  JOB   DEPTNO 
---------- --------- ---------- 
JONES  MANAGER   20 
CLARK  MANAGER   10 
PARAG  MANAGER   30 

Questo funziona anche:

SQL> select ename, job, deptno from emp 
    2 where (ename, deptno) in (('JONES',20),('CLARK',10)); 

ENAME  JOB   DEPTNO 
---------- --------- ---------- 
JONES  MANAGER   20 
CLARK  MANAGER   10 
NON

IN troppo:

SQL> select ename, job, deptno from emp 
    2 where (ename, deptno) not in 
    3 (select ename, deptno from emp 
    4 where job = 'MANAGER' 
    5 ); 

ENAME  JOB   DEPTNO 
---------- --------- ---------- 
SMITH  CLEANER   99 
SCOTT  ANALYST   20 
KING  PRESIDENT   10 
FORD  ANALYST   20 
MILLER  CLERK    10 
+0

Lui sta chiedendo di "NON IN". Non solo "IN" –

+0

@David Oneill - non puoi presumere che se uno funziona, lo stesso fa l'altro? – froadie

+0

Aggiunto NON IN esempio solo per essere sicuro ! –

2

usare Google suggerisce che funzionerà su alcuni database, ma non altri. È possibile utilizzare questo invece:

SELECT DISTINCT a, b, c 
FROM t1 
WHERE NOT EXISTS 
    (SELECT 1 FROM t2 
    WHERE t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c) 
0

Altri hanno già risposto alla domanda, ma come un suggerimento prestazioni, se hai a che fare con dati di qualsiasi dimensioni significative utilizzare sempre il EXISTS dichiarazione piuttosto che IN. Sarà più veloce in quasi tutti i casi.

http://decipherinfosys.wordpress.com/2007/01/21/32/

Problemi correlati