2011-11-04 17 views
2

例如,只有一列的簡單表。 即。sql - 單個查詢返回不存在的值

CREATE TABLE movies (title VARCHAR2(255 BYTE)) 

設置與以下數據:

INSERT INTO movies (title) VALUES ('Scream'); 
INSERT INTO movies (title) VALUES ('Blair Witch'); 
INSERT INTO movies (title) VALUES ('Friday the 13th'); 
INSERT INTO movies (title) VALUES ('Scary Movie'); 
INSERT INTO movies (title) VALUES ('Hide and Seek'); 
INSERT INTO movies (title) VALUES ('Alien vs Predator'); 

是否有一個單一的查詢或PL/SQL,將做動態以下(即,無需手動做一個「UNION選擇‘尖叫’來自雙重......「對於每個價值)?

顯然這個查詢錯誤的,但你的想法:

Select * from movies 
where title in (
'Scream', 
'Scary Movie', 
'Exorcist', 
'Dracula', 
'Saw', 
'Hide and Seek' 
) 

期望的結果是在「WHERE稱號」的條款每個值,其中記錄不存在於表中的記錄。 即。

'Exorcist' 
'Dracula' 
'Saw' 
+0

選中的行所有的方法來從關係(表)。您必須在某個時刻創建一個表格,可能是「UNION select」尖叫「來自雙重...」,就像您所說的每個值。 – danihp

回答

3

如果您使用10g或更高版本,你可以建立,其中轉換的CSV字符串轉換爲動態表功能檢查這些代碼的字符串標記。在this other response

你會使用這樣的:

select * from movies 
where title NOT in (
     select * 
      from table (string_tokenizer 
         (
          'Scream, Scary Movie,Exorcist,Dracula,Saw,Hide and Seek' 
         ) 

       ) 
    ) 
/

這裏有一個稍微簡單的實現,它不需要任何額外的infrastru cture:

SQL> select * from table(sys.dbms_debug_vc2coll('Scream', 
'Scary Movie', 
'Exorcist', 
'Dracula', 
'Saw', 
'Hide and Seek' 
)) 
/
    2 3 4 5 6 7 8 
COLUMN_VALUE 
-------------------------------------------------------------------------------- 
Scream 
Scary Movie 
Exorcist 
Dracula 
Saw 
Hide and Seek 

6 rows selected. 

SQL> 

這類似於the Table Value Constructor,但它僅適用於單個列「表」工作。

+0

關鍵字'table'和名稱'sys.dbms_debug_vc2coll'是我一直在尋找的。幫助我避免多次重複「union select」。謝謝! –

1

您可以使用表類型和函數表()將列表轉換爲表。

CREATE OR REPLACE TYPE varchar_list_type as table of varchar2(100); 

CREATE OR REPLACE function in_varchar_list (p_string in varchar2) return varchar_list_type 
as 
    l_data    varchar_list_type := varchar_list_type(); 
    l_string   long default p_string || ','; 
    l_n    number; 
begin 

    loop 
     exit when l_string is null; 

     l_data.extend; 
     l_n := instr(l_string, ','); 
     l_data(l_data.count) := substr(l_string, 1, l_n-1); 
     l_string := substr(l_string, l_n+1); 

    end loop; 
    return l_data; 
end; 

然後,使用這樣的:

select * from TABLE(select cast(in_varchar_list('foo,bar,baz') as varchar_list_type) from dual) 

Ofcourse你可以使用綁定變量或正常的變量,而不是硬編碼字符串「富,酒吧,巴茲」。

編輯:錯字查詢^ _ ^」

2

你想要的是「表值構造器」功能。我不認爲Oracle支持這一點。

見喬·塞科的有關文章:Table Value Constructors in SQL Server 2008 AMD的從那裏取例如:

SELECT * 
FROM 
    (VALUES 
     (101, 'Bikes'), 
     (102, 'Accessories'), 
     (103, 'Clothes') 
) AS Category(CategoryID, CategoryName); 
+0

恥辱oracle沒有這個 – toop

+0

我認爲DB2也有它。和最新的(2008)版本的SQL服務器。 –

+0

PostgreSQL也有。 –