ibr*_*ter 5 postgresql aggregate array like postgresql-9.4
有什么方法可以对 postgresql 中的数组元素进行模式匹配(9.4,如果版本有所不同)?我有一个聚合函数,除其他外,它返回一个元素数组,例如:
SELECT
lognum
,array_agg(flightnum) as flightnums
FROM logs
GROUP BY lognum;
Run Code Online (Sandbox Code Playgroud)
其中flightnum
字段是包含文本字符串或三或四位数字的 varchar。现在假设我要选择航班号以“8”开头的所有日志(即“800”或“8000”系列航班)。我的第一个想法是做这样的事情:
SELECT
*
FROM (
SELECT
lognum
,array_agg(flightnum) as flightnums
FROM logs
GROUP BY
lognum
) s1
WHERE
'8%' like ANY(flightnums);
Run Code Online (Sandbox Code Playgroud)
但是,虽然这不会给出错误,但它也不会返回任何结果。我猜测这是因为通配符位于运算符的左侧。当然,反过来就是:
WHERE ANY(flightnum) like '8%'
Run Code Online (Sandbox Code Playgroud)
给我一个语法错误。那么有什么方法可以运行此查询,以便获得包含以 8(或其他)开头的航班号的任何行吗?
请注意,这是一个简化的示例,仅演示了我遇到困难的部分。
我最终做的是编写一个“换向器”运算符。在 postgres 中,我使用以下两个命令创建了一个新函数和运算符:
create function like_rev (text, text) returns boolean as $$ select $2 like $1 $$ language SQL;
create operator ~~~~ (procedure = like_rev, leftarg=text, rightarg=text);
Run Code Online (Sandbox Code Playgroud)
它实际上与 a 相同like
,但在比较时颠倒了参数顺序。like
所以现在我可以通过简单地替换为 来实现对数组进行通配符匹配的目标~~~~
,如下所示:
SELECT
*
FROM (
SELECT
lognum,
array_agg(flightnum) as flightnums
FROM logs
GROUP BY
lognum
) s1
WHERE
'8%' ~~~~ ANY(flightnums);
Run Code Online (Sandbox Code Playgroud)
请注意,这可能不是性能最高的解决方案 - 如果您需要最高性能,Cassandra 的答案很可能会更好。但是,这对我来说效果很好,因为它不需要对查询结构进行任何更改。
归档时间: |
|
查看次数: |
5672 次 |
最近记录: |