我在 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
读取数据时对数据进行排序吗? (这意味着数据将始终是较新的,因为它是从旧->新读取的)。
我不是 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;