在 PostgreSQL 中使用 UNNEST() 加入,以访问触发器的 OF 列名称

JOIN with UNNEST() in PostgreSQL, to access a trigger's OF column names

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

当我 select 触发器的列数组 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,试图将数组扩展到它的 ,知道
对于有问题的触发器,前一个连接 select 一行。

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)

一个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)