2017-06-11 36 views
0

在查詢Teradata時,我被使用NOT LIKE ANY關鍵字發現。
從簡單的英語解析關鍵字,我希望查詢返回任何值不像參數列表中的值。有什麼情況下使用不像任何東西是有道理的?

但是,由於該語句生成的布爾邏輯(即NOT LIKE X OR NOT LIKE Y),表中的所有值都被返回。我實際需要的關鍵字是NOT LIKE ALL(即NOT LIKE X AND NOT LIKE Y)。

An example using Postgresql

CREATE TABLE t 
    ("col" varchar(7)) 
; 

INSERT INTO t 
    ("col") 
VALUES 
    ('Andrew'), 
    ('Annie'), 
    ('Bob'), 
    ('Bowie'), 
    ('Charles') 
; 

/* Returns 'Charles' */ 
select col 
from t 
where col not like all (array[ 'An%', 'Bo%' ]) 
; 

/* Returns all values in table */ 
select col 
from t 
where col not like any (array[ 'An%', 'Bo%' ]) 
; 

我理解其背後的原因正在返回這些結果的基本邏輯,但我的問題是,是否有任何環境,此時將是有意義的使用NOT LIKE ANY

如果沒有,數據庫引擎是否有足夠的理由支持這個關鍵字,因爲基於簡單英文解釋關鍵字的可能性不明確?

+1

你可以在SQL中做很多愚蠢的事情:-)真的不需要'NOT LIKE ANY',但由於語法允許否定任何條件,因此必須支持它。順便說一句,大多數人(包括我自己)在布爾邏輯方面存在問題,涉及'NOT' – dnoeth

+0

是的好點。我自己已經完成了我愚蠢的事情。我想我已經考慮過,大多數關鍵字都是爲特定目的而設計的,而不是由布爾邏輯的組成部分構建的布爾邏輯 – Alex

回答

1

是的,它有一定道理,有輕微的修改是一樣的。

藉此查詢:

SELECT g 
FROM generate_series(9995, 10005) g 
WHERE g::TEXT NOT LIKE ANY(ARRAY['9996','9997']) 

如果g就是其中NOT LIKE任何,則返回TRUE。感興趣的項目是數字9996和9997.由於9996不是NOT LIKE 9996,因此9996與數組中第一項的比較結果爲FALSE。但我們正在查找任何匹配,因此我們繼續前進到下一個。 9996不像9997,因此評估爲TRUE且包含9996。當比較9997時相同,但第一個比較返回TRUE。因此,所有來自generate_series的數字都被選中。

現在稍微改變它:

SELECT g 
FROM generate_series(9995, 10005) g 
WHERE NOT g::TEXT LIKE ANY(ARRAY['9996','9997']) 

,因爲任何停止的,只要一個比較返回TRUE評估(我試圖找到這來的官方消息,但不能,但十分肯定我讀了它之前和它是有道理的),當使用LIKE將9996與9996進行比較時,ANY搜索因找到匹配而中止。然後由NOT抵消,因此9996不包括在結果中。

與9997類似的故事,除了第一個比較不是TRUE,所以它繼續到下一個,也就是說,TRUE然後被否定爲FALSE。其餘的數字不匹配,所以ANY返回FALSE,否則返回TRUE。

如果此查詢是來自generate_series的除9996和9997之外的所有數字,則結果。順便說一下,如果數組只有一個值,那麼g::TEXT NOT LIKE ANY([your array])將返回預期結果。

+0

Hehe。 :-)#1翻譯爲'g不喜歡9996或不喜歡9997',而#2導致'g不喜歡9996和g不喜歡9997' – dnoeth

+0

這很有趣。我猜想我認爲'NOT LIKE ANY'本身就是一個關鍵詞,而不是由'NOT','LIKE'和'ANY'組成。我想我明白它是如何評估上面兩個例子中的不同值的。儘管如此,我仍然期望它評估爲「NOT(LIKE ANY(X,Y))」而不是「NOT LIKE(ANY(X,Y))」。 – Alex

+0

...雖然我仍然不確定我是否有這個權利。 Dnoeth已經成爲頭上的負責人......負面的條件邏輯是令人困惑的** – Alex

0

如果您使用的是ANY而不是ALL,則不排除任何行。這裏的ANY就像OR一樣。因此,在任何情況下,您都可以使用OR來代替IN,您可以使用ANY

最好不要使用ANY,因爲我們製作的等於沒equal.ie爲IN

相關問題