簡體   English   中英

sql-單個查詢以返回不存在的值

[英]sql - single query to return values that are not present

例如,您有一個只有一列的簡單表。 即。

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 TITLE IN”子句中每個值的記錄,其中表中不存在該記錄。 即。

'Exorcist'
'Dracula'
'Saw'

如果您使用的是10g或更高版本,則可以構建一個將CSV字符串轉換為動態表的函數。 另一個響應中簽出字符串標記符的代碼。

您可以這樣使用它:

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

                  )
     )
/

這是一個稍微簡單的實現,不需要任何其他基礎結構:

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> 

這類似於表值構造器 ,但僅適用於單列“表”。

您需要的是“表值構造函數”功能。 我不認為Oracle支持這一點。

請參閱Joe Celko的文章,內容涉及: SQL Server 2008中的表值構造函數以及從中獲取的示例:

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

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

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)

當然,您可以使用綁定變量或普通變量來代替硬編碼字符串'foo,bar,baz'。

編輯:查詢^ _ ^中的錯字

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM