Postgres:将连接结果插入为数组?

Ado*_*obe 2 postgresql

这是我所拥有的:

\n\n
=# SELECT * FROM users;\n id |     name      \n----+---------------\n  1 | Paul Gilbert\n  2 | Bob Dylan\n  3 | Cliff Downing\n\n=# SELECT * FROM regs;\n reg_id | user_id \n--------+---------\n      1 |       1\n     11 |       1\n    111 |       1\n      2 |       2\n     22 |       2\n      3 |       3\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是我想要获得的:

\n\n
=# SELECT * FROM joined;\n id |     name      |       regs\n----+---------------+-------------------\n  1 | Paul Gilbert  | {1, 11, 111}\n  2 | Bob Dylan     | {2, 22}\n  3 | Cliff Downing | {3}\n
Run Code Online (Sandbox Code Playgroud)\n\n

微量元素:

\n\n
-- create users table:\nDROP TABLE users;\nCREATE TABLE users(\n   id    INT      PRIMARY KEY  NOT NULL,\n   name  VARCHAR               NOT NULL\n);\n-- populate users table:\nINSERT INTO users (id, name)\nVALUES (1, \'Paul Gilbert\'),\n       (2, \'Bob Dylan\'),\n       (3, \'Cliff Downing\');\n\n\n-- reg table:\nDROP TABLE regs;\nCREATE TABLE regs(\n   reg_id   INT  PRIMARY KEY  NOT NULL,\n   user_id  INT               NOT NULL\n);\n-- populate reg table:\nINSERT INTO regs (reg_id, user_id)\nVALUES (1,   1),\n       (11,  1),\n       (111, 1),\n       (2,   2),\n       (22,  2),\n       (3,   3);\n\n\n-- joined table:\nDROP TABLE joined;\nCREATE TABLE joined(\n    id    INT,\n    name  VARCHAR,\n    regs  INT[]\n);\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是我迄今为止的努力:

\n\n
BEGIN;\n  INSERT INTO joined (id, name)\n       SELECT id, name\n         FROM users;\n\n  INSERT INTO joined (regs)\n       SELECT ARRAY(\n                   SELECT reg_id\n                     FROM regs\n               INNER JOIN joined\n                       ON joined.id = regs.user_id\n                   );\nCOMMIT;\n
Run Code Online (Sandbox Code Playgroud)\n\n

它不起作用:

\n\n
 id |     name      |               regs\n----+---------------+-----------------------------------\n  1 | Paul Gilbert  | \n  2 | Bob Dylan     | \n  3 | Cliff Downing | \n    |               | {1,11,111,2,22,3}\n
Run Code Online (Sandbox Code Playgroud)\n\n

编辑

\n\n

a_horse_with_no_name的解决方案效果很好。

\n\n

您认为有办法在单个表达式中添加另一个连接吗?

\n\n
CREATE TABLE ldap.univer_users(\n  first_name  VARCHAR,\n  middle_name VARCHAR,\n  last_name   VARCHAR,\n  code        VARCHAR,\n  doc_number  VARCHAR,\n  reg_numbers VARCHAR[]\n);\n\nBEGIN;\n    INSERT INTO ldap.univer_users (first_name, middle_name, last_name, code, reg_numbers)\n    SELECT\n        d."firstName", d."middleName", d."lastName", d.uid, array_agg(r."regNumber")\n    FROM\n        student_data d\n        JOIN student_reg_numbers r ON d.uid = r.student_datum_uid\n    GROUP BY d.uid;\n\n    UPDATE ldap.univer_users\n    SET doc_number = p.doc_number\n    FROM (\n            SELECT student_datum_uid, substring(number FROM \'....$\') AS doc_number\n            FROM student_passports\n            WHERE "passportType" IN (\'\xd0\x9f\xd0\xb0\xd1\x81\xd0\xbf\xd0\xbe\xd1\x80\xd1\x82 \xd0\xa0\xd0\xa4\', \'\xd0\x9f\xd0\xb0\xd1\x81\xd0\xbf\xd0\xbe\xd1\x80\xd1\x82 \xd0\xb8\xd0\xbd\xd0\xbe\xd1\x81\xd1\x82\xd1\x80\xd0\xb0\xd0\xbd\xd0\xbd\xd0\xbe\xd0\xb3\xd0\xbe \xd0\xb3\xd1\x80\xd0\xb0\xd0\xb6\xd0\xb4\xd0\xb0\xd0\xbd\xd0\xb8\xd0\xbd\xd0\xb0\')\n         ) p\n    WHERE code = p.student_datum_uid;\nCOMMIT;\n
Run Code Online (Sandbox Code Playgroud)\n\n

这适用于我的数据,但我很好奇是否有办法将其放入单个insert语句中。

\n\n

编辑2

\n\n

尝试将所有内容统一在一个表达式中:

\n\n
INSERT INTO ldap.univer_users (first_name, middle_name, last_name, code, doc_number, reg_numbers)\nSELECT\n    d."firstName", d."middleName", d."lastName", d.uid, substring(p.number FROM \'....$\'), array_agg(r."regNumber")\nFROM\n    student_data d\n    JOIN student_reg_numbers r ON d.uid = r.student_datum_uid\n    JOIN student_passports   p ON d.uid = p.student_datum_uid\n      AND p."passportType" IN (\'\xd0\x9f\xd0\xb0\xd1\x81\xd0\xbf\xd0\xbe\xd1\x80\xd1\x82 \xd0\xa0\xd0\xa4\', \'\xd0\x9f\xd0\xb0\xd1\x81\xd0\xbf\xd0\xbe\xd1\x80\xd1\x82 \xd0\xb8\xd0\xbd\xd0\xbe\xd1\x81\xd1\x82\xd1\x80\xd0\xb0\xd0\xbd\xd0\xbd\xd0\xbe\xd0\xb3\xd0\xbe \xd0\xb3\xd1\x80\xd0\xb0\xd0\xb6\xd0\xb4\xd0\xb0\xd0\xbd\xd0\xb8\xd0\xbd\xd0\xb0\')\nGROUP BY d.uid;\n
Run Code Online (Sandbox Code Playgroud)\n\n

Postgres 说

\n\n
=# SELECT * FROM users;\n id |     name      \n----+---------------\n  1 | Paul Gilbert\n  2 | Bob Dylan\n  3 | Cliff Downing\n\n=# SELECT * FROM regs;\n reg_id | user_id \n--------+---------\n      1 |       1\n     11 |       1\n    111 |       1\n      2 |       2\n     22 |       2\n      3 |       3\n
Run Code Online (Sandbox Code Playgroud)\n

小智 5

您需要使用一条insert语句:

INSERT INTO joined (id, name, regs)
SELECT u.id, u.name, array_agg(reg_id)
FROM users u
  JOIN regs r ON r.user_id = u.id
GROUP BY u.id, u.name;
Run Code Online (Sandbox Code Playgroud)

您的两步方法需要 anupdate作为第二步,而不是insert

INSERT INTO joined (id, name)
SELECT id, name
FROM users;

update joined 
   set regs = t.regs
from (  
  select user_id, array_agg(reg_id) as regs
  from regs
  group by user_id
) t
where t.user_id = joined.id;
Run Code Online (Sandbox Code Playgroud)