在 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 行,值 2
和 3
,然后我可以
`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)
我想要 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 行,值 2
和 3
,然后我可以
`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)