如何对SELECTed ARRAY列执行通配符WHERE子句

时间:2015-09-08 18:07:20

标签: sql database postgresql subquery

我有以下SQL。我试图将结果限制为仅包含与特定术语匹配的任何标签(在标签列表中)的结果。这个SQL被简化了 - 还有更多的列和表 - 但希望这能说明我遇到的问题。

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)

在这个例子中,我只想要具有术语" sale"标签中的任何地方:: label_ lable_group'出现在每行的标签列表中。为了进一步解释,我希望任何具有任何标签的行,例如" saleorder :: presales"。

所以,当然,当我运行上面的查询时,我得到了这个:

ERROR:  column "label_list" does not exist

我在StackOverflow上学到了为什么它不起作用,我明白了。

然后我尝试将子查询复制/粘贴到我的谓词中:

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

我没有错误,但也没有匹配,即使有一个" saleorder :: presales"标签

有趣的是,当我输入一个文字(非通配符)label_name :: label_group值时,例如:

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

我得到一个匹配,好像ILIKE表现得像=而不是。

我需要能够在这种类型的列中搜索通配符值,并且在尝试不同的事情几个小时之后就无法解决这个问题。我很感激任何见解。

1 个答案:

答案 0 :(得分: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%')