在 Postgres 中的多行插入查询中返回插入行的索引
Returning Index of inserted rows in a multiple row insert query in Postgres
我正在尝试在 PostgresSQL 11.2 中使用一个 Insert SQL 查询插入多行(大约 1k)。像这样:
insert into foo(id) values(6),(5),(4),(3),(2) ON CONFLICT DO NOTHING RETURNING id;
它 return 插入行的 ID 很好。但如果获得插入行的索引(从 0 开始)对我来说会很棒。
例如,考虑在 ID 为 5 和 3(索引 1 和 3)的行中插入 5 行有冲突,目标是这样的:
indexes
------------
0
2
4
有什么想法吗?对我来说很重要的是只用一个查询就可以做到这一点。
我认为您不能 return 一个不在目标 table 中的值。但是假设这些值是唯一的,您可以使用 join
:
来计算
with v as (
select v.*
from (values(0, 6), (1, 5), (2, 4), (3, 3), (4, 2)
) v(idx, id)
),
i as (
insert into foo(id)
select id
from v
on conflict do nothing
returning id
)
select v.*
from v join
i
on v.id = i.id;
恐怕无法 return 您插入的 table 中不存在的值。
也许 CTE
and the window function row_number
的组合可以达到目的:
测试数据
CREATE TABLE foo(id INT PRIMARY KEY);
INSERT INTO foo VALUES (5),(3);
查询
WITH k AS (
WITH j AS (
VALUES (6),(5),(4),(3),(2) -- here you place your 1k entries!
) SELECT column1,row_number() OVER (ORDER BY 1)-1 AS idx FROM j
), l AS (
INSERT INTO foo SELECT DISTINCT column1 FROM k
ON CONFLICT DO NOTHING RETURNING id)
SELECT idx FROM l
JOIN k ON k.column1 = l.id ORDER BY idx;
idx
-----
0
2
4
(3 Zeilen)
我正在尝试在 PostgresSQL 11.2 中使用一个 Insert SQL 查询插入多行(大约 1k)。像这样:
insert into foo(id) values(6),(5),(4),(3),(2) ON CONFLICT DO NOTHING RETURNING id;
它 return 插入行的 ID 很好。但如果获得插入行的索引(从 0 开始)对我来说会很棒。
例如,考虑在 ID 为 5 和 3(索引 1 和 3)的行中插入 5 行有冲突,目标是这样的:
indexes
------------
0
2
4
有什么想法吗?对我来说很重要的是只用一个查询就可以做到这一点。
我认为您不能 return 一个不在目标 table 中的值。但是假设这些值是唯一的,您可以使用 join
:
with v as (
select v.*
from (values(0, 6), (1, 5), (2, 4), (3, 3), (4, 2)
) v(idx, id)
),
i as (
insert into foo(id)
select id
from v
on conflict do nothing
returning id
)
select v.*
from v join
i
on v.id = i.id;
恐怕无法 return 您插入的 table 中不存在的值。
也许 CTE
and the window function row_number
的组合可以达到目的:
测试数据
CREATE TABLE foo(id INT PRIMARY KEY);
INSERT INTO foo VALUES (5),(3);
查询
WITH k AS (
WITH j AS (
VALUES (6),(5),(4),(3),(2) -- here you place your 1k entries!
) SELECT column1,row_number() OVER (ORDER BY 1)-1 AS idx FROM j
), l AS (
INSERT INTO foo SELECT DISTINCT column1 FROM k
ON CONFLICT DO NOTHING RETURNING id)
SELECT idx FROM l
JOIN k ON k.column1 = l.id ORDER BY idx;
idx
-----
0
2
4
(3 Zeilen)