sql >> データベース >  >> RDS >> PostgreSQL

1つのテーブルと多対多のテーブルへの複数のINSERT

    すべてを1つで行うことができます CTEを使用したSQLコマンド。

    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

    詳細な説明

    同時書き込みがある場合 あなたはもっとやらなければならないかもしれません。特に2番目のリンクを検討してください。




    1. mysqlの単一クエリで2つのテーブルを更新します

    2. 非アクティブな時間の後に接続がハングする

    3. PostgreSQL11.1で既存の列をIdentityとして変更するにはどうすればよいですか?

    4. 問題セット1-エンティティの特定