在 PostgreSQL 中使用 UNNEST() 连接,以访问触发器的 OF 列名

Posted

技术标签:

【中文标题】在 PostgreSQL 中使用 UNNEST() 连接,以访问触发器的 OF 列名【英文标题】:JOIN with UNNEST() in PostgreSQL, to access a trigger's OF column names 【发布时间】:2020-11-09 12:25:57 【问题描述】:

我想选择触发器的OF 列的名称(如果可能,按顺序)。

当我选择触发器的列 numbers 数组时,它工作正常。

D:\pdgm\trunk\psc2>psql -h nemo
Password for user ddevienne:
psql (12.1, server 12.0)
...
ddevienne=> SELECT t.tgattr
ddevienne->   FROM pg_namespace n
ddevienne->   JOIN pg_class     c ON c.relnamespace = n.oid
ddevienne->   JOIN pg_trigger   t ON t.tgrelid      = c.oid
ddevienne->  WHERE n.nspname = 'public'
ddevienne->    AND c.relname = 'ut_trigger'
ddevienne->    AND t.tgname = 'keepnamehistorytrigger'
ddevienne-> ;
 tgattr
--------
 2 3
(1 row)

但是当我尝试 UNNEST 将该数组与 pg_attributes 连接时,如果失败。 这是一个correlated-join,试图将数组扩展到它的,知道 前面的连接选择了一行,作为有问题的触发器。

ddevienne=> SELECT trig_cols.col_num
ddevienne->   FROM pg_namespace n
ddevienne->   JOIN pg_class     c ON c.relnamespace = n.oid
ddevienne->   JOIN pg_trigger   t ON t.tgrelid      = c.oid
ddevienne->   JOIN UNNEST(t.tgattr) as trig_cols(col_num)
ddevienne->  WHERE n.nspname = 'public'
ddevienne->    AND c.relname = 'ut_trigger'
ddevienne->    AND t.tgname = 'keepnamehistorytrigger'
ddevienne-> ;
ERROR:  syntax error at or near "WHERE"
LINE 6:  WHERE n.nspname = 'public'
         ^
ddevienne=>

我期待 2 行,值 23,然后我可以 `JOIN pg_attribute a ON a.attrelid = c.oid AND a.attnum = trig_cols.col_num```。

我错过了什么?谢谢,--DD

更新

谢谢。我错过了ON true(或CROSS JOIN)。 这是最终版本,使用WITH ORDINALITY 保留顺序。

ddevienne=> SELECT a.attname
ddevienne->   FROM pg_namespace n
ddevienne->   JOIN pg_class     c ON c.relnamespace = n.oid
ddevienne->   JOIN pg_trigger   t ON t.tgrelid      = c.oid
ddevienne->   JOIN UNNEST(t.tgattr) WITH ORDINALITY as trig_cols(col_num, col_idx) ON true
ddevienne->   JOIN pg_attribute a ON a.attrelid     = c.oid
ddevienne->                      AND a.attnum       = trig_cols.col_num
ddevienne->   WHERE n.nspname = 'public'
ddevienne->    AND t.tgname = 'keepnamehistorytrigger'
ddevienne->    AND c.relname = 'ut_trigger'
ddevienne->  ORDER BY trig_cols.col_idx
ddevienne-> ;
 attname
----------
 name
 Alt_Name
(2 rows)

【问题讨论】:

【参考方案1】:

JOIN 需要一个连接条件:

SELECT trig_cols.col_num
  FROM pg_namespace n
  JOIN pg_class     c ON c.relnamespace = n.oid
  JOIN pg_trigger   t ON t.tgrelid      = c.oid
  JOIN UNNEST(t.tgattr) as trig_cols(col_num) ON true --<< here
 WHERE n.nspname = 'public'
   AND c.relname = 'ut_trigger'
   AND t.tgname = 'keepnamehistorytrigger'

交替使用

CROSS JOIN UNNEST(t.tgattr) as trig_cols(col_num)

【讨论】:

以上是关于在 PostgreSQL 中使用 UNNEST() 连接,以访问触发器的 OF 列名的主要内容,如果未能解决你的问题,请参考以下文章

具有 unnest 的 PostgreSQL 查询不返回空值的结果行

PostgreSQL unnest,嵌套字段特定元素的 WHERE 子句

postgresql - 不嵌套,对于每个结果

Postgresql一行变多行unnest与string_to_array,多行变一行string_agg

使用 Psycopg2 和 unnest 时的“未知”数据类型

将 UNNEST 与 jOOQ 一起使用