插入许多返回id的行,并在另一个表中更新该ID

时间:2017-03-16 18:41:01

标签: sql postgresql

我正在使用PostgreSQL,我的sql结构:

CREATE TEMP TABLE users (
    id_user serial,
    user_name varchar,
    id_user_description int
);

CREATE TEMP TABLE user_description  (
    id_user_description serial,
    age int
);

users表有一些用户:

INSERT INTO users (user_name)
SELECT column1
FROM (
    VALUES
    ('John'),
    ('Amanda')
) t;

我正在尝试将数据插入表user_description,我还需要将插入的行ID更新到表users。我的疑问是:

WITH inserted_user_description AS (
    INSERT INTO user_description (age)
    SELECT age
    FROM (
        SELECT users.id_user,
            t.column1 AS age,
            t.column2 AS user_name
        FROM (
            VALUES
            (21, 'John'),
            (28, 'Amanda')
        ) t
        INNER JOIN users ON users.user_name = t.column2
    ) tt
    RETURNING id_user_description, tt.id_user
)
UPDATE users SET id_user_description = t.id_user_description
FROM (
    SELECT id_user_description, id_user
    FROM inserted_user_description 
) t
WHERE users.id_user = t.id_user;

但我得到错误:

  

错误:缺少表“tt”的FROM子句条目   第15行:返回id_user_description,tt.id_user

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

这是一个有效的SQL代码段,说明了它的工作原理。您有2个表ab。您希望在b中插入行时更新a

ab架构:

CREATE TABLE a (
    id serial unique,
    some_int int
);

CREATE TABLE b (
    id serial,
    a_id int,
    some_date timestamp
);

让我们在b中插入一些行,以匹配我们将在a中插入的行(它们是我们将要更新的行):

INSERT INTO b (a_id, some_date)
SELECT generate_series, null
FROM generate_series(1, 100);

现在,这是如何在a中插入行并更新b中的等效行:

WITH inserted as (
    INSERT INTO a (some_int)
    SELECT *
    FROM generate_series(1, 10)
    RETURNING id
)
UPDATE b
SET some_date = NOW()
FROM inserted i
WHERE i.id = b.a_id
;

如您所见,插入a的10行和b中更新的10个等效行:

test=# SELECT * FROM a;
 id | some_int 
----+----------
  1 |        1
  2 |        2
  3 |        3
  4 |        4
  5 |        5
  6 |        6
  7 |        7
  8 |        8
  9 |        9
 10 |       10
(10 rows)

test=# SELECT * FROM b WHERE some_date IS NOT NULL;
 id | a_id |         some_date          
----+------+----------------------------
  1 |    1 | 2017-03-16 17:48:32.257217
  2 |    2 | 2017-03-16 17:48:32.257217
  3 |    3 | 2017-03-16 17:48:32.257217
  4 |    4 | 2017-03-16 17:48:32.257217
  5 |    5 | 2017-03-16 17:48:32.257217
  6 |    6 | 2017-03-16 17:48:32.257217
  7 |    7 | 2017-03-16 17:48:32.257217
  8 |    8 | 2017-03-16 17:48:32.257217
  9 |    9 | 2017-03-16 17:48:32.257217
 10 |   10 | 2017-03-16 17:48:32.257217
(10 rows)

<强>更新

在您的具体情况下,我认为您的查询应该是这样的(在没有架构的情况下总是难以编写查询!):

WITH inserted_user_description AS (
    INSERT INTO user_description (age, <...>)
    SELECT u.id_user,
        t.column1 AS age,
        <...>
        t.column8 AS user_name
    FROM (
        VALUES
        (21, <...> ,'John'),
        (28, <...> ,'Amanda'),
        <...>
    ) t
    JOIN users u ON u.user_name = t.user_name
    RETURNING id_user_description, u.id_user
)
UPDATE users
SET id_user_description = t.id_user_description
FROM inserted_user_description t
WHERE users.id_user = t.id_user;