sql >> Database >  >> RDS >> PostgreSQL

Meerdere INSERTS in één tabel en veel tot veel tafels

Je kunt het allemaal in één SQL-opdracht met behulp van CTE's.

Ervan uitgaande dat Postgres 9,6 en dit klassieke veel-op-veel-schema (omdat je het niet hebt opgegeven):

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

Een enkele invoegen vraag met een array van 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 hier

Dit creëert direct alle tags die nog niet bestaan.

De tekstrepresentatie van een Postgres-array ziet er als volgt uit:{tag1, tag2, tag3} .

Als de invoerarray gegarandeerd verschillende tags heeft, kunt u DISTINCT . verwijderen van de CTE input_tags .

Gedetailleerde uitleg :

Als u gelijktijdige schrijfbewerkingen . heeft misschien moet je meer doen. Denk vooral aan de tweede link.




  1. Het bijwerken van MySQL retourneert de betreffende rijen, maar werkt de database niet echt bij

  2. Hoe ISO8601 naar datumformaat te converteren in php

  3. Hoe de activiteit van één database in SQL Server te analyseren

  4. MySql kan de bovenliggende rij niet bijwerken als ik ON UPDATE CASCADE heb