2015-09-08 42 views
0

我有以下SQL。我試圖將結果限制爲只有具有與特定術語匹配的任何標籤(在標籤列表中)的結果。這個SQL簡化了 - 還有更多的列和表格 - 但希望這會說明我遇到的問題。如何對SELECTed ARRAY列執行通配符WHERE子句

SELECT 
    account_id 
    , ARRAY(SELECT(label_name || '::' || label_group) AS label 
      FROM labels) AS label_list 

FROM accounts 

WHERE 
    account_id = 1 

AND 
    '%sale%' ILIKE ANY (label_list) 

在這個例子中,我只希望那些在出現在標籤中的每一行的列表中的「LABEL_NAME :: lable_group」「買賣」一詞在任何地方行。爲了進一步解釋,我希望任何有諸如「saleorder :: presales」之類的標籤的行。

所以,當然,當我運行上面的查詢,我得到這個:

ERROR: column "label_list" does not exist 

我StackOverflow上了解到爲什麼不工作,我理解這一點。

於是我試圖複製/粘貼子查詢到我的謂詞:

AND 
'%sale%' ILIKE ANY (SELECT(label_name || '::' || label_group) 
        FROM labels) 

,我沒有錯誤,也儘管有一個「saleorder ::預售」的標籤不匹配。

有趣的是,雖然,當I型文字(非通配符)LABEL_NAME :: label_group值如:

AND 
'saleorder::presales' ILIKE ANY (SELECT(label_name || '::' || label_group) 
           FROM labels) 

我得到一個匹配,因爲如果被ILIKE表現得像=代替。

我需要能夠搜索這種類型的通配符值的列,並且在嘗試不同的事情後經過幾個小時才找不到它。我會很感激任何見解。

+2

樣本數據和預期的結果將真正幫助解釋您的問題。 SQL小提琴也很有幫助。 –

+0

你確定要使用'ARRAY'嗎?在你的情況下,創建一個包含所有標籤的字符串的大小爲1的數組 –

回答

0

該模式在ILIKE的錯誤一側。你基本上有'%bar%' ilike 'foobar',而你需要'foobar' ilike '%bar%'。我不知道你的情況,各地交換他們的一種優雅的方式......

我能想出的最好的事情是:

select * from(
SELECT 
    account_id 
    , ARRAY(SELECT(label_name || '::' || label_group) AS label 
      FROM labels) AS label_list 
FROM accounts 
WHERE 
    account_id = 1 
)X 
where exists(select * from unnest(label_list) U where U ilike '%sale%') 
+0

要交換它們,需要定義一個自定義運算符,該運算符調用一個包裝器SQL函數,該函數依次執行'ilike',然後將該運算符用作「ANY」術語中的「逆向」。有點麻煩。 –