在Postgres中的多行插入查询中返回插入行的索引

时间:2019-12-09 06:06:49

标签: sql postgresql upsert

我试图在PostgresSQL 11.2中使用一个Insert SQL查询插入多行(大约1k)。像这样的东西:

insert into foo(id) values(6),(5),(4),(3),(2) ON CONFLICT DO NOTHING RETURNING id;

它返回插入的行的ID,这很好。但是,如果对插入的行获取索引(从0开始),这对我来说是很棒的。

例如,考虑将具有冲突的5行插入ID为5和3(索引1和3)目标的行中,如下所示:

indexes
------------
0
2
4

有什么主意吗?对于我来说,仅执行一个查询就很重要。

2 个答案:

答案 0 :(得分:1)

我认为您无法返回目标表中没有的值。但是,假设值是唯一的,则可以使用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;

答案 1 :(得分:1)

恐怕无法返回您要插入的表中不存在的值。

也许CTE和窗口函数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)