Space 在 PostgreSQL 中输出整数值
Space out integer values in PostgreSQL
我有一个 table 具有唯一的 int 字段,该字段目前在 PostgreSQL 数据库中保存(大部分)连续值。
我想以相同的顺序更新这些值,从最小值开始,但要确保这些值之间存在一些整数差。
间距为 100 的示例:
before | after
-------|-------
516 | 516
520 | 616
1020 | 716
1021 | 816
1022 | 916
1816 | 1016
我尝试用序列解决这个问题,但找不到保持顺序的简单方法,因为 UPDATE
不能使用 ORDER BY
。
这是一次性 'housekeeping' 任务,需要几百个条目,所以效率不高。
您可以使用 PL
或 DO
来执行此操作(如果您真的不必再次执行此操作)。这是一个演示,说明如何使用 DO
-- Temporal table for the demo:
CREATE TEMP TABLE demo (id integer,somecolumn integer);
INSERT INTO demo VALUES
(12,6766),
(22,9003),
(33,8656),
(50,6995),
(69,9151),
(96,9160);
-- DO function, here is where you make the ID change.
DO $$
DECLARE
new_id integer := NULL;
row integer := 0;
rows_count integer := 0;
BEGIN
-- Create a temp table to change the id that will be droped at the end.
-- This table should have the same colums as the original table.
CREATE TEMP TABLE demo_temp (id integer,somecolumn integer) ON COMMIT DROP;
-- Get the initial id
new_id := id FROM demo ORDER BY id LIMIT 1;
-- Get the rows count for the loop
rows_count := COUNT(*) FROM demo;
LOOP
-- Insert into temp table adding the new id.
-- This loops for every row to make sure you have the same order and data.
INSERT into demo_temp(id,somecolumn)
SELECT new_id,somecolumn FROM demo ORDER BY id LIMIT 1 OFFSET row;
-- Adding 100 to id
new_id := new_id+100;
-- Loop control
row := row+1;
EXIT WHEN rows_count = row;
END LOOP;
-- Clean original table
TRUNCATE demo;
-- Insert temp table with new id
INSERT INTO demo(id,somecolumn) SELECT id,somecolumn FROM demo_temp;
END $$;
-- See result:
SELECT * FROM demo;
最后一个 select 返回新的 Table:
New Table: Old Table:
id | somecolumn id | somecolumn
----+------------- ----+-------------
12 | 6766 12 | 6766
112 | 9003 22 | 9003
212 | 8656 33 | 8656
312 | 6995 50 | 6995
412 | 9151 69 | 9151
512 | 9160 96 | 9160
我有一个 table 具有唯一的 int 字段,该字段目前在 PostgreSQL 数据库中保存(大部分)连续值。
我想以相同的顺序更新这些值,从最小值开始,但要确保这些值之间存在一些整数差。
间距为 100 的示例:
before | after
-------|-------
516 | 516
520 | 616
1020 | 716
1021 | 816
1022 | 916
1816 | 1016
我尝试用序列解决这个问题,但找不到保持顺序的简单方法,因为 UPDATE
不能使用 ORDER BY
。
这是一次性 'housekeeping' 任务,需要几百个条目,所以效率不高。
您可以使用 PL
或 DO
来执行此操作(如果您真的不必再次执行此操作)。这是一个演示,说明如何使用 DO
-- Temporal table for the demo:
CREATE TEMP TABLE demo (id integer,somecolumn integer);
INSERT INTO demo VALUES
(12,6766),
(22,9003),
(33,8656),
(50,6995),
(69,9151),
(96,9160);
-- DO function, here is where you make the ID change.
DO $$
DECLARE
new_id integer := NULL;
row integer := 0;
rows_count integer := 0;
BEGIN
-- Create a temp table to change the id that will be droped at the end.
-- This table should have the same colums as the original table.
CREATE TEMP TABLE demo_temp (id integer,somecolumn integer) ON COMMIT DROP;
-- Get the initial id
new_id := id FROM demo ORDER BY id LIMIT 1;
-- Get the rows count for the loop
rows_count := COUNT(*) FROM demo;
LOOP
-- Insert into temp table adding the new id.
-- This loops for every row to make sure you have the same order and data.
INSERT into demo_temp(id,somecolumn)
SELECT new_id,somecolumn FROM demo ORDER BY id LIMIT 1 OFFSET row;
-- Adding 100 to id
new_id := new_id+100;
-- Loop control
row := row+1;
EXIT WHEN rows_count = row;
END LOOP;
-- Clean original table
TRUNCATE demo;
-- Insert temp table with new id
INSERT INTO demo(id,somecolumn) SELECT id,somecolumn FROM demo_temp;
END $$;
-- See result:
SELECT * FROM demo;
最后一个 select 返回新的 Table:
New Table: Old Table:
id | somecolumn id | somecolumn
----+------------- ----+-------------
12 | 6766 12 | 6766
112 | 9003 22 | 9003
212 | 8656 33 | 8656
312 | 6995 50 | 6995
412 | 9151 69 | 9151
512 | 9160 96 | 9160