PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Множество INSERT в една таблица и много към много таблица

Можете да направите всичко в едно SQL команда, използваща CTE.

Приемаме Postgres 9.6 и тази класическа схема много към много (тъй като не сте я предоставили):

CREATE TABLE questions (
  question_id serial PRIMARY KEY
, title text NOT NULL
, body text
, userid int
, categoryid int
);

CREATE TABLE tags (
  tag_id serial PRIMARY KEY
, tag text NOT NULL UNIQUE);

CREATE TABLE questiontags (
  question_id int REFERENCES questions
, tag_id      int REFERENCES tags
, PRIMARY KEY(question_id, tag_id)
);

За вмъкване на сингъл въпроса с масив от тагове :

WITH input_data(body, userid, title, categoryid, tags) AS (
   VALUES (:title, :body, :userid, :tags)
   )
 , input_tags AS (                         -- fold duplicates
      SELECT DISTINCT tag
      FROM   input_data, unnest(tags::text[]) tag
      )
 , q AS (                                  -- insert question
   INSERT INTO questions
         (body, userid, title, categoryid)
   SELECT body, userid, title, categoryid
   FROM   input_data
   RETURNING question_id
   )
 , t AS (                                  -- insert tags
   INSERT INTO tags (tag)
   TABLE  input_tags  -- short for: SELECT * FROM input_tags
   ON     CONFLICT (tag) DO NOTHING        -- only new tags
   RETURNING tag_id
   )
INSERT INTO questiontags (question_id, tag_id)
SELECT q.question_id, t.tag_id
FROM   q, (
   SELECT tag_id
   FROM   t                                -- newly inserted
   UNION  ALL
   SELECT tag_id
   FROM   input_tags JOIN tags USING (tag) -- pre-existing
   ) t;

dbfiddle тук

Това създава всички тагове, които все още не съществуват в движение.

Текстовото представяне на масив на Postgres изглежда така:{tag1, tag2, tag3} .

Ако е гарантирано, че входният масив има различни тагове, можете да премахнете DISTINCT от CTE input_tags .

Подробно обсяснение :

Ако имате едновременни записи може да се наложи да направите повече. Помислете по-специално за втората връзка.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да преобразувате тип bytea до двойна точност

  2. Регистрирайте конкретна заявка за postgresql с помощта на pg-promise

  3. Как трябва да използвам Postgresql docker изображение/контейнер?

  4. Добавените записи в базата данни се изтриват след рестартиране на приложението (heroku/SQLAlchemy)

  5. Не може да се свърже с Postgres DB поради тип удостоверяване 10 не се поддържа