2012-04-03 15 views
7

Take tej tabeli SŁOWAOracle SQL - znajdź NIE wartości w tabeli

WORD 
Hello 
Aardvark 
Potato 
Dog 
Cat 

i to listę:

('Hello', 'Goodbye', 'Greetings', 'Dog') 

Jak mogę zwrócić listę słów, które nie znajdują się w tablice słów, ale są na mojej liście?

Jeśli mam tabelę, która „zawiera wszystkie możliwe słowa”, mogę zrobić:

SELECT * from ALL_WORDS_TABLE 
where word in ('Hello', 'Goodbye', 'Greetings', 'Dog') 
and word not in 
(SELECT word from WORDS 
where word in ('Hello', 'Goodbye', 'Greetings', 'Dog') 
); 

Jednak nie mam takiego stołu. Jak inaczej można to zrobić?

Ponadto, tworzenie nowej tabeli nie jest opcją, ponieważ nie mam takiego poziomu dostępu.

Odpowiedz

25

Zamiast ciężko kodowania wartości list na wiersze, użyj DBMS_DEBUG_VC2COLL dynamicznie zamienić ograniczoną listę do wierszy, a następnie użyć operatora MINUS wyeliminować wiersze w drugim zapytaniu, które są nie w pierwszym pytaniu:

select column_value 
from table(sys.dbms_debug_vc2coll('Hello', 'Goodbye', 'Greetings', 'Dog')) 
minus 
select word 
from words; 
+0

Przyjemna technika) Ale co, jeśli odmówiono dostępu do funkcji sys. *? – denied

+0

@denied No cóż, byłoby to naprawdę niezręczne. Mogą istnieć inne sposoby zamiany rozdzielonej listy ciągów na kolumnę, która jest bardziej elegancka niż sys.dbms_debug_vc2coll. Być może istnieje rozwiązanie wykorzystujące czysty SQL? – Wolf

+0

@Denied W tym kontekście 'sys' nie jest złą rzeczą. Ktoś mógłby teoretycznie odmówić ci dostępu do tego typu, ale prawdopodobnie nie jest to coś, o co musisz się martwić. Jest prawie tak samo prawdopodobne, jak ktoś, kto usuwa dostęp do 'sys.dbms_output'. –

5

Można włączyć swoją listę do widoku tak:

select 'Hello' as word from dual 
union all 
select 'Goodbye' from dual 
union all 
select 'Greetings' from dual 
union all 
select 'Dog' from dual 

Następnie można wybrać, że:

select * from 
(
    select 'Hello' as word from dual 
    union all 
    select 'Goodbye' from dual 
    union all 
    select 'Greetings' from dual 
    union all 
    select 'Dog' from dual 
) 
where word not in (select word from words); 

prawdopodobnie nie wymienia jako rozwiązanie, jak można się spodziewać ..

Mówisz, że nie masz wystarczających uprawnień do tworzenia tabel, więc prawdopodobnie nie możesz tworzyć typów - ale jeśli znajdziesz odpowiedni typ "leżąc" w bazie danych, możesz zrobić to:

select * from table (table_of_varchar2_type('Hello','Goodbye','Greetings','Dog')) 
where column_value not in (select word from words); 

Tutaj table_of_varchar2_type jest sobie wyobrazić, aby być nazwa typu, który jest zdefiniowany następująco:

create type table_of_varchar2_type as table of varchar2(100); 

Jeden taki typ jest prawdopodobne, aby być w stanie znaleźć to SYS.KU$_VCNT której znajduje się tabela VARCHAR2 (4000).

4

Spróbuj tego rozwiązania:

SELECT 
a.word 
FROM 
(
SELECT 'Hello' word FROM DUAL UNION 
SELECT 'Goodbye' word FROM DUAL UNION 
SELECT 'Greetings' word FROM DUAL UNION 
SELECT 'Dog' word FROM DUAL 
) a 
LEFT JOIN ALL_WORDS_TABLE t ON t.word = a.word 
WHERE 
t.word IS NULL 
Powiązane problemy