在 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)