PostgreSQL: SELECTクエリ結果をまるごと挿入する魔法の構文 INSERT INTO ... (SELECT * ...)

2024-04-02

PostgreSQL: INSERT INTO ... (SELECT * ...) の詳細解説

INSERT INTO ... (SELECT * ...) は、PostgreSQL における強力なデータ挿入構文です。この構文は、SELECT クエリによって取得された結果をまるごと別のテーブルに挿入するために使用されます。

構文

INSERT INTO 対象テーブル名 (列名1, 列名2, ...)
SELECT 列名1, 列名2, ...
FROM データソース;

解説

  • INSERT INTO: データを挿入するテーブルを指定します。
  • 対象テーブル名: データを挿入するテーブルの名前を記述します。
  • (列名1, 列名2, ...): 挿入する列を指定します。省略可能です。
  • SELECT: 挿入するデータを取得するSELECTクエリを記述します。
  • 列名1, 列名2, ...: SELECTクエリで取得する列を指定します。
  • FROM: データを取得するテーブルまたはサブクエリを記述します。

-- テーブル`users`から`name`と`email`列をすべて`customers`テーブルに挿入
INSERT INTO customers (name, email)
SELECT name, email
FROM users;

-- SELECTクエリ結果に基づいて`orders`テーブルにデータ挿入
INSERT INTO orders (product_id, quantity)
SELECT product_id, quantity
FROM cart
WHERE user_id = 123;

ポイント

  • * を使用すると、SELECTクエリで取得されたすべての列を挿入できます。
  • INSERT する列とSELECT する列は、名前と順序が一致する必要があります。
  • WHERE 句などの条件を SELECT クエリに追加することで、挿入するデータの絞り込みができます。
  • INSERT INTO ... (SELECT ...) は、大量のデータを効率的に挿入するのに役立ちます。

補足

  • より高度なデータ挿入には、ON CONFLICT 句などを活用できます。

関連キーワード

  • SQL
  • PostgreSQL
  • INSERT
  • SELECT
  • ON CONFLICT



テーブル作成

-- サンプルテーブル作成
CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  email VARCHAR(255) NOT NULL
);

CREATE TABLE orders (
  id SERIAL PRIMARY KEY,
  user_id INTEGER NOT NULL,
  product_id INTEGER NOT NULL,
  quantity INTEGER NOT NULL
);

データ挿入

-- usersテーブルにデータ挿入
INSERT INTO users (name, email)
VALUES ('John Doe', '[email protected]'),
       ('Jane Doe', '[email protected]');

-- ordersテーブルにデータ挿入
INSERT INTO orders (user_id, product_id, quantity)
VALUES (1, 100, 1),
       (1, 200, 2),
       (2, 100, 3);

SELECTクエリによるデータ挿入

-- usersテーブルからnameとemail列をすべてcustomersテーブルに挿入
INSERT INTO customers (name, email)
SELECT name, email
FROM users;

-- SELECTクエリ結果に基づいてordersテーブルにデータ挿入
INSERT INTO orders (product_id, quantity)
SELECT product_id, quantity
FROM cart
WHERE user_id = 123;

補足




PostgreSQL: INSERT INTO の他の方法

VALUES 句による挿入

INSERT INTO users (name, email)
VALUES ('John Doe', '[email protected]'),
       ('Jane Doe', '[email protected]');

RETURNING 句

INSERT INTO users (name, email)
VALUES ('John Doe', '[email protected]')
RETURNING id;

COPY コマンド

COPY users (name, email)
FROM '/path/to/file.csv'
DELIMITER ','
CSV HEADER;

INSERT ... ON CONFLICT

INSERT INTO orders (user_id, product_id, quantity)
VALUES (1, 100, 1)
ON CONFLICT (user_id, product_id) DO UPDATE
SET quantity = quantity + 1;

PL/pgSQL を使用した挿入

DO $$
BEGIN
  FOR i IN 1..10 LOOP
    INSERT INTO users (name, email)
    VALUES (CONCAT('user', i), CONCAT('user', i, '@example.com'));
  END LOOP;
END;
$$;

これらの方法はそれぞれ異なる利点と欠点があります。状況に応じて最適な方法を選択する必要があります。

  • VALUES
  • COPY
  • PL/pgSQL

sql postgresql insert


pglogicalとDebeziumによるリアルタイムクロスデータベースクエリ

postgres_fdw は、PostgreSQL 9.1 以降で利用可能な公式の外国データラッパー (FDW) です。 FDW は、あたかもローカルテーブルであるかのように、リモートデータベースのテーブルにアクセスするための仕組みを提供します。 postgres_fdw を使用すると、以下のことができます。...


SQL GROUP BY句とHAVING句で条件付きSUM集計:グループ化されたデータの分析

最も基本的な方法は、WHERE句を使用して条件を指定することです。この方法は、単純な条件に適しています。例: 特定の顧客の注文合計を計算するHAVING句は、GROUP BY句と共に使用して、集計結果に対して条件を指定することができます。これは、グループ化されたデータに対して条件付きSUMを適用する場合に役立ちます。...


BULK INSERTを使ってCSVファイルをSQL Serverにインポートする方法

CSVファイルは、カンマ区切りでデータを記述したファイルフォーマットです。シンプルな構造のため、様々なツールで扱えます。一方、SQL Serverは、データベース管理システムです。CSVファイルのデータをSQL Serverにインポートすることで、データ分析や管理が容易になります。...


MySQLでカレンダーテーブルを使って日付範囲の集計で日付のギャップをなくす

このような場合、以下の2つの方法で日付のギャップをなくすことができます。方法1:共通テーブル式 (CTE) を使用するMySQL 8.0以降では、CTEを使用して日付範囲を生成し、集計テーブルと結合することで、日付のギャップをなくすことができます。...


PostgreSQLスキーマ作成エラー「must be member of role」:スーパーユーザー権限で強行突破

このエラーは、PostgreSQLでスキーマを作成しようとした際に、スキーマを作成しようとしているユーザーが、そのスキーマの所有者となるロールのメンバーではない場合に発生します。エラーメッセージ:例:上記の例では、my_schemaというスキーマを作成しようとしましたが、エラーが発生しました。これは、現在のユーザーがmy_schema_ownerというロールのメンバーではないためです。...