从具有多个冲突条件的 4 列表中复制 3 列

问题描述 投票:0回答:1

我在 postgres 中有两组数据,第一组(错误地)使用 bigserial 作为键:

CREATE TABLE info_tbl (
    id bigserial NOT NULL,
    "uuid" uuid NOT NULL,
    "time_stamp" timestamp NOT NULL,
    "json_thing" jsonb NOT NULL,
    CONSTRAINT info_tbl_pkey PRIMARY KEY (id)
);

正确的表生成如下(以uuid为主键):

CREATE TABLE info_tbl_correct (
    "uuid" uuid NOT NULL,
    "time_stamp" timestamp NOT NULL,
    "json_thing" jsonb NOT NULL,
    CONSTRAINT info_tbl_correct_pkey PRIMARY KEY (uuid)
);

我一直在尝试生成 posgres 代码以将旧数据从

info_tbl
复制到
info_tbl_correct
,但是我遇到了困难,因为当它检测到冲突时,我只想复制具有较新时间戳的数据。

INSERT INTO info_tbl_correct
("uuid", "time_stamp", "json_thing")
SELECT src."uuid", src."time_stamp", src."json_thing"
FROM info_tbl AS src
ON CONFLICT ("uuid")
DO UPDATE 
SET "time_stamp"=EXCLUDED."time_stamp", "json_thing"=EXCLUDED."json_thing";

我可以让 postgres 支持两种冲突情况吗?或者我可以在从

info_tbl
读取数据时对数据进行排序吗? (这意味着数据将始终是较新的,因为它是从旧->新读取的)。

postgresql
1个回答
0
投票

我不是 psotgre 专家。不过,你可以试试这个。 您可以通过结合使用 ROW_NUMBER() 和 PARTITION BY 对 info_tbl 中的数据进行排序,然后再将其插入 info_tbl_ Correct 来实现此目的。这样,即使存在冲突,您也可以确保插入较新的数据。

这是您可以使用的 SQL 查询:

WITH cte AS (
    SELECT
        "uuid",
        "time_stamp",
        "json_thing",
        ROW_NUMBER() OVER (PARTITION BY "uuid" ORDER BY "time_stamp" DESC) AS rn
    FROM info_tbl
)
INSERT INTO info_tbl_correct ("uuid", "time_stamp", "json_thing")
SELECT "uuid", "time_stamp", "json_thing"
FROM cte
WHERE rn = 1
ON CONFLICT ("uuid") DO NOTHING;
© www.soinside.com 2019 - 2024. All rights reserved.