我在下面的表中需要用表2的最新值更新表1,而无需创建中间临时表。
表1
| environment | division | item | item_cost |
| ----------- | -------- | ---- | --------- |
| 'local' | 'first' | 'item-U' | 0 |
| 'local-queue' | 'first' | 'item-U' | 0 |
| 'denmark' | 'first' | 'item-U' | 0 |
| 'local' | 'first' | 'item-C' | 0 |
| 'local-queue' | 'first' | 'item-C' | 0 |
| 'denmark' | 'first' | 'item-C' | 0 |
| 'local' | 'second' | 'item-E' | 0 |
| 'local' | 'second' | 'item-L' | 0 |
表2
| environment | division | item | item_cost |
| ----------- | -------- | ---- | --------- |
| 'denmark' | 'second' | 'item-E' | 1666 |
| 'local' | 'second' | 'item-E' | 4444 |
| 'denmark' | 'first' | 'item-U' | 18080 |
| 'denmark' | 'first' | 'item-U' | 18079 |
| 'local' | 'first' | 'item-U' | 55555 |
是否可以将Table-2合并到Table-1中,使Table-2的最新值低于输出?
| environment | division | item | item_cost |
| ----------- | -------- | ---- | --------- |
| 'local' | 'first' | 'item-U' | 55555 |
| 'local-queue' | 'first' | 'item-U' | 0 |
| 'denmark' | 'first' | 'item-U' | 18080 |
| 'local' | 'first' | 'item-C' | 0 |
| 'local-queue' | 'first' | 'item-C' | 0 |
| 'denmark' | 'first' | 'item-C' | 0 |
| 'local' | 'second' | 'item-E' | 4444 |
| 'local' | 'second' | 'item-L' | 0 |
我有一个传统的方法,可以创建一个临时表,然后查找并更新。
我只是想知道是否有一种方法可以在不创建临时表的情况下即时获得所需的输出。
表2中的某些条目可能不需要在输出中显示。
谢谢。
答案 0 :(得分:0)
您需要考虑使用SQL进行基于集合的操作,并假设它总是可能的。使用两个集合,并尝试通过遍历集合1来更新集合2而不是使用SQL一次完成所有操作,这是一个常见错误。
我可以回答您的问题,但是由于至少两个原因,您的示例不清楚:
假设环境,部门和项目是唯一的,则这是合并两组数据的正确方法。尝试插入新记录,如果键已经存在,则更新该键的item_cost:
INSERT INTO table_1 (environment, division, item, item_cost)
SELECT environment, division, item, item_cost
FROM table_2
ON CONFLICT (environment, division, item)
DO UPDATE
SET item_cost = EXCLUDED.item_cost;
ON CONFLICT
受Postgres 9.5+支持。
如果table_2行已经与table_1行相同,则最好执行以下稍微复杂一些的操作,以避免重复更新数据:
-- Only return rows that are actually different from what is already in table_1
WITH actual_data_diff AS
(SELECT environment, division, item, item_cost
FROM table_2
EXCEPT ALL
SELECT environment, division, item, item_cost
FROM table_1)
INSERT INTO table_1 (environment, division, item, item_cost)
SELECT environment, division, item, item_cost
FROM actual_data_diff
ON CONFLICT (environment, division, item)
DO UPDATE
SET item_cost = EXCLUDED.item_cost;
在报告环境中,您通常会获得大量的冗余写入,从而导致过多的膨胀和WAL流量,而上述模式仅允许进行实际更改,可以轻松避免这种情况。
有一个MERGE
声明正在积极开发中,可能会与PG12一起发布。