我们正在尝试使用旧表中的信息为新功能填充新表,但我们将多次将此查询作为脚本运行,因为我们想要捕获任何用户更新的数据。
表 1 架构。
table1
id | email | first_name | last_name | job | phone | user_id | institution_id | institution_type | completion_state | created_at | updated_at | mobile_phone | deleted_at
----+-------+------------+-----------+-----+-------+---------+----------------+------------------+------------------+------------+------------+--------------+------------
Run Code Online (Sandbox Code Playgroud)
表 2 架构。
table2
id | contact_id | status | data | created_at | updated_at | source_updated_at
----+------------+--------+------+------------+------------+-------------------
Run Code Online (Sandbox Code Playgroud)
这是我的查询
INSERT INTO table2 AS iic (contact_id, data, created_at, updated_at, source_updated_at)
SELECT
cc.id,
(
SELECT row_to_json(_) FROM (
SELECT
cc.email,
cc.first_name,
cc.last_name,
cc.job,
cc.phone,
cc.user_id,
cc.institution_id,
cc.institution_type,
cc.completion_state,
cc.updated_at,
cc.mobile_phone,
inst.type,
inst.name,
inst.description,
inst.assets_under_management,
inst.phone,
add.id,
add.street,
add.street2,
add.city,
add.state,
add.country,
add.zip_code
) AS _
) AS data,
current_timestamp,
current_timestamp,
cc.updated_at
FROM table1 cc
LEFT JOIN institutions inst
ON cc.institution_id = inst.id
LEFT JOIN addresses add
ON add.addressable_id = inst.id
ON CONFLICT (contact_id) DO
UPDATE SET status = 'updated',
source_updated_at = excluded.updated_at
WHERE iic.source_updated_at != excluded.updated_at;
Run Code Online (Sandbox Code Playgroud)
因此,我们将表 1 的信息复制到表 2 中。我们第一次运行它时,一切都完美地复制过来,状态列为空。如果我然后更改 table1 上单行的更新日期,我希望
ON CONFLICT ... UPDATE
Run Code Online (Sandbox Code Playgroud)
只会在 updated_at 行发生更改的情况下触发和更新 table2。相反,它将 table2 上的所有状态更改为已更新。
我怀疑 WHERE 子句不是特定于行的,而是适用于更大的集合,在这种情况下,此条件将始终返回 true。但是,如果有人可以阐明我如何修改我的查询以返回我正在寻找的内容,那就太好了。
如果有任何需要澄清的地方,请告诉我。
干杯,
postgres v.9.6.11
在@a_horse_with_no_name 的帮助下,我能够在我的想法中找到错误。PostgresSQL文档中有一个很好的例子,它真正为我澄清了这一点:
根据需要插入或更新新的经销商。假设已定义唯一索引来限制出现在 did 列中的值。请注意,特殊排除表用于引用最初建议插入的值:
Run Code Online (Sandbox Code Playgroud)INSERT INTO distributors (did, dname) VALUES (5, 'Gizmo Transglobal'), (6, 'Associated Computing, Inc') ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED.dname;
我最初的想法是该EXCLUDED表使用了与我试图从中插入的表相同的列名。实际上,它引用了我试图插入的表的列名,但这些值是最初建议插入的。
所以,我的查询的结尾应该是这样的:
...
ON CONFLICT (contact_id) DO
UPDATE SET status = 'updated',
source_updated_at = EXCLUDED.source_updated_at
WHERE iic.source_updated_at != EXCLUDED.source_updated_at;
Run Code Online (Sandbox Code Playgroud)
感谢您成为我的橡皮鸭,我希望这可以帮助其他人!
| 归档时间: |
|
| 查看次数: |
6347 次 |
| 最近记录: |