sql >> Database teknologi >  >> RDS >> PostgreSQL

Flere INSERTS i en tabel og mange til mange tabeller

Du kan gøre det hele på én SQL-kommando ved hjælp af CTE'er.

Forudsat Postgres 9.6 og dette klassiske mange-til-mange-skema (da du ikke har leveret det):

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

For at indsætte en enkelt spørgsmål med en matrix af tags :

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 her

Dette opretter alle tags, der endnu ikke eksisterer i farten.

Tekstrepræsentationen af ​​et Postgres-array ser sådan ud:{tag1, tag2, tag3} .

Hvis input-arrayet er garanteret at have distinkte tags, kan du fjerne DISTINCT fra CTE input_tags .

Detaljeret forklaring :

Hvis du har samtidige skrivninger du skal muligvis gøre mere. Overvej især det andet link.




  1. Array af forespørgsler til 'for await'-løkke til postgresql-transaktionshjælper

  2. Omdøb dublerede rækker i MySQL

  3. Hukommelse/lagringsteknologihierarki og SQL Server

  4. Hvordan kan jeg udføre ikke-forespørgsel Stored Procedure i JDBC