sql >> Databáze >  >> RDS >> PostgreSQL

Více VLOŽENÍ do jedné tabulky a mnoho do mnoha tabulek

Můžete to udělat vše v jednom SQL příkaz pomocí CTE.

Za předpokladu, že Postgres 9.6 a toto klasické schéma many-to-many (protože jste jej neposkytli):

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

Chcete-li vložit single otázka s řadou značek :

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 zde

Tím se vytvoří všechny značky, které zatím neexistují.

Textová reprezentace Pole Postgres vypadá takto:{tag1, tag2, tag3} .

Pokud je zaručeno, že vstupní pole bude mít odlišné značky, můžete odstranit DISTINCT z CTE input_tags .

Podrobné vysvětlení :

Pokud máte souběžné zápisy možná budete muset udělat víc. Zvažte zejména druhý odkaz.




  1. Seskupit MySQL podle dat mezi

  2. Chyba syntaxe dotazu Postgres sql z phpPgAdmin

  3. Sloupec podobný identitě, ale založený na kritériích Seskupit podle

  4. Jak zaškrtnout nebo nezaškrtnout stav zaškrtávacího políčka založené na hodnotách databáze?