你可以这样做
CREATE TABLE thetable (event_id string, batt_id string, serial_number string, batt_key number);
INSERT INTO thetable VALUES('1','bat1','1',0);
INSERT INTO thetable VALUES('2','bat1','1',0);
因此,使用您想要的基本形式的表格,其中包含一些虚拟行以显示“我们想要使用基于 battery_id 的现有密钥的预先存在的数据。出于打字原因,我缩小了列名,并使用数字字符串而不是 UUID,但点仍然成立。
CREATE OR REPLACE SEQUENCE batt_key_seq;
WITH new_data(event_id, batt_id, serial_number) AS (
SELECT * FROM VALUES
('11','bat1', '10'),
('12','bat1', '10'),
('13','bat2', '11'),
('14','bat1', '10'),
('15','bat1', '10'),
('16','bat2', '11'),
('17','bat3', '12')
), new_data_with_keys AS (
SELECT d.batt_id
,COALESCE(t.batt_key, batt_key_seq.nextval) AS batt_key
FROM (
SELECT DISTINCT batt_id
FROM new_data
) AS d
LEFT JOIN thetable AS t
ON d.batt_id = t.batt_id
QUALIFY row_number() OVER (PARTITION BY d.batt_id ORDER BY event_id) = 1
)
SELECT n.*, k.batt_key
FROM new_data AS n
JOIN new_data_with_keys AS k
ON n.batt_id = k.batt_id
;
所以 ROW_NUMBER() 部分是只捕获现有行之一(因此在开始时在现有数据中插入双数据),我觉得这可能会更干净一些其他方式,但它完成了工作.
但实际上你得到了你的密钥,你找到了现有的密钥,并为新数据提供了新的密钥,然后可以以这种丰富的形式插入数据。
我在测试中注意到的是,我的键每次运行都会跳 4 次,然后切换到
,IFF(t.batt_key is not null, t.batt_key, batt_key_seq.nextval) AS batt_key
没有解决这个问题。
所以分离关键发现部分,如
WITH new_data(event_id, batt_id, serial_number) AS (
SELECT * FROM VALUES
('11','bat1', '10'),
('12','bat1', '10'),
('13','bat2', '11'),
('14','bat1', '10'),
('15','bat1', '10'),
('16','bat2', '11'),
('17','bat3', '12')
), missing_keys AS (
SELECT d.batt_id
,batt_key_seq.nextval AS batt_key
FROM (
SELECT DISTINCT batt_id
FROM new_data
) AS d
LEFT JOIN thetable AS t
ON d.batt_id = t.batt_id
WHERE t.batt_id IS NULL
), old_keys AS (
SELECT distinct d.batt_id
,t.batt_key
FROM (
SELECT DISTINCT batt_id
FROM new_data
) AS d
LEFT JOIN thetable AS t
ON d.batt_id = t.batt_id
WHERE t.batt_id IS NOT NULL
), new_data_with_keys AS (
SELECT * FROM missing_keys
UNION ALL
SELECT * FROM old_keys
)
SELECT n.*, k.batt_key
FROM new_data AS n
JOIN new_data_with_keys AS k
ON n.batt_id = k.batt_id
;
现在新密钥不会跳过/浪费。
双连接与键空间浪费的性能差异是您可能需要测试和/或了解您将看到多少新诗与现有数据以及因此发生多少浪费的东西。如果第二个的性能差异很大,您可以随时重新键入数据,尽管这些键在表之外使用,可能会在以后更新大量数据。