Postgresql:与数组元素的模式匹配?

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(或其他)开头的航班号的任何行吗?


请注意,这是一个简化的示例,仅演示了我遇到困难的部分。

ibr*_*ter 4

我最终做的是编写一个“换向器”运算符。在 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 的答案很可能会更好。但是,这对我来说效果很好,因为它不需要对查询结构进行任何更改。