Postgresql-with-clause
PostgreSQL-WITH句
PostgreSQLでは、WITHクエリは、より大きなクエリで使用する補助ステートメントを記述する方法を提供します。 複雑で大規模なクエリを簡単に読みやすい形式に分解するのに役立ちます。 これらのステートメントは、よくCommon Table ExpressionsまたはCTEと呼ばれ、1つのクエリに対してのみ存在する一時テーブルを定義すると考えることができます。
WITHクエリはCTEクエリであり、サブクエリが複数回実行される場合に特に役立ちます。 一時テーブルの代わりにも同様に役立ちます。 集計を一度計算し、クエリでその名前(複数回の場合もある)で参照できるようにします。
WITH句は、クエリで使用する前に定義する必要があります。
構文
WITHクエリの基本的な構文は次のとおりです-
WITH
name_for_summary_data AS (
SELECT Statement)
SELECT columns
FROM name_for_summary_data
WHERE conditions <=> (
SELECT column
FROM name_for_summary_data)
[ORDER BY columns]
_name_for_summary_data_は、WITH句に指定された名前です。 name_for_summary_dataは既存のテーブル名と同じにすることができ、優先されます。
WITHでデータ変更ステートメント(INSERT、UPDATE、またはDELETE)を使用できます。 これにより、同じクエリで複数の異なる操作を実行できます。
再帰的WITH
例
次のようなレコードを持つテーブルlink:/postgresql/company.sql [COMPANY]を考慮してください-
testdb# select *from COMPANY;
id | name | age | address | salary
----+-------+-----+-----------+--------
1 | Paul | 32 | California| 20000
2 | Allen | 25 | Texas | 15000
3 | Teddy | 23 | Norway | 20000
4 | Mark | 25 | Rich-Mond | 65000
5 | David | 27 | Texas | 85000
6 | Kim | 22 | South-Hall| 45000
7 | James | 24 | Houston | 10000
(7 rows)
さて、次のように、上記のテーブルからレコードを選択するWITH句を使用してクエリを記述しましょう-
With CTE AS
(Select
ID
, NAME
, AGE
, ADDRESS
, SALARY
FROM COMPANY )
Select* From CTE;
上記のPostgreSQLステートメントは、次の結果を生成します-
id | name | age | address | salary
----+-------+-----+-----------+--------
1 | Paul | 32 | California| 20000
2 | Allen | 25 | Texas | 15000
3 | Teddy | 23 | Norway | 20000
4 | Mark | 25 | Rich-Mond | 65000
5 | David | 27 | Texas | 85000
6 | Kim | 22 | South-Hall| 45000
7 | James | 24 | Houston | 10000
(7 rows)
今、私たちは次のように、20000未満の給与の合計を見つけるために、WITH句と一緒にRECURSIVEキーワードを使用してクエリを書いてみましょう-
WITH RECURSIVE t(n) AS (
VALUES (0)
UNION ALL
SELECT SALARY FROM COMPANY WHERE SALARY < 20000
)
SELECT sum(n) FROM t;
上記のPostgreSQLステートメントは、次の結果を生成します-
sum
-------
25000
(1 row)
以下に示すように、WITH句とともにデータ変更ステートメントを使用してクエリを記述しましょう。
最初に、表COMPANYと同様の表COMPANY1を作成します。 例のクエリは、行をCOMPANYからCOMPANY1に効果的に移動します。 WITHのDELETEは、指定された行をCOMPANYから削除し、RETURNING句によってその内容を返します。そして、プライマリクエリはその出力を読み取り、COMPANY1 TABLEに挿入します-
CREATE TABLE COMPANY1(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);
WITH moved_rows AS (
DELETE FROM COMPANY
WHERE
SALARY >= 30000
RETURNING *
)
INSERT INTO COMPANY1 (SELECT *FROM moved_rows);
上記のPostgreSQLステートメントは、次の結果を生成します-
INSERT 0 3
さて、テーブルCOMPANYとCOMPANY1のレコードは次のとおりです-
testdb=# SELECT* FROM COMPANY;
id | name | age | address | salary
----+-------+-----+------------+--------
1 | Paul | 32 | California | 20000
2 | Allen | 25 | Texas | 15000
3 | Teddy | 23 | Norway | 20000
7 | James | 24 | Houston | 10000
(4 rows)
testdb=# SELECT * FROM COMPANY1;
id | name | age | address | salary
----+-------+-----+-------------+--------
4 | Mark | 25 | Rich-Mond | 65000
5 | David | 27 | Texas | 85000
6 | Kim | 22 | South-Hall | 45000
(3 rows)