【问题标题】:How to execute a wildcard WHERE clause against a SELECTed ARRAY column如何对 SELECTed ARRAY 列执行通配符 WHERE 子句
【发布时间】:2015-09-08 18:07:19
【问题描述】:

我有以下 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)

在这个例子中,我只想要在每行的标签列表中出现的 'label_name::lable_group' 中任何地方都包含“sale”一词的行。为了进一步解释,我想要任何具有任何标签的行,例如“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 的行为类似于 =。

我需要能够在这种类型的列中搜索通配符值,但在尝试了几个小时不同的事情之后却无法弄清楚。如有任何见解,我将不胜感激。

【问题讨论】:

  • 样本数据和期望的结果确实有助于解释您的问题。 SQL Fiddle 也很有帮助。
  • 您确定要使用ARRAY吗?在您的情况下,创建一个大小为 1 的数组,其中包含一个包含所有标签的字符串

标签: sql database postgresql subquery


【解决方案1】:

模式在 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%')

【讨论】:

  • 要交换它们,您需要定义一个自定义运算符,该运算符调用包装 SQL 函数,该函数依次执行 ilike,然后将该运算符用作 ANY 术语中的“反向 ilike” .有点麻烦。
猜你喜欢
  • 1970-01-01
  • 2018-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
  • 2012-03-14
  • 1970-01-01
  • 2017-10-13
相关资源
最近更新 更多