追加のモジュールtablefunc
は、機能を提供するデータベースごとに1 回インストールしますcrosstab()
。Postgres 9.1以降でCREATE EXTENSION
は、次のように使用できます。
CREATE EXTENSION IF NOT EXISTS tablefunc;
テストケースの改善
CREATE TABLE tbl (
section text
, status text
, ct integer -- "count" is a reserved word in standard SQL
);
INSERT INTO tbl VALUES
('A', 'Active', 1), ('A', 'Inactive', 2)
, ('B', 'Active', 4), ('B', 'Inactive', 5)
, ('C', 'Inactive', 7); -- ('C', 'Active') is missing
単純なフォーム-欠落している属性には適合しません
crosstab(text)
1つの入力パラメータ:
SELECT *
FROM crosstab(
'SELECT section, status, ct
FROM tbl
ORDER BY 1,2' -- needs to be "ORDER BY 1,2" here
) AS ct ("Section" text, "Active" int, "Inactive" int);
戻り値:
セクション| アクティブ| 非活性
--------- + -------- + ----------
A | 1 | 2
B | 4 | 5
C | 7 | -!!
- キャストや名前の変更は必要ありません。
- の誤った結果に注意してください。最初の列に
C
値7
が入力されています。この動作は望ましい場合がありますが、このユースケースでは望ましくありません。
- シンプルなフォームもに限定されて正確にします。入力クエリ内の3つの列ROW_NAME、カテゴリ、値。以下の2パラメータの代替のように、追加の列を配置する余地はありません。
安全なフォーム
crosstab(text, text)
2つの入力パラメータ:
SELECT *
FROM crosstab(
'SELECT section, status, ct
FROM tbl
ORDER BY 1,2' -- could also just be "ORDER BY 1" here
, $$VALUES ('Active'::text), ('Inactive')$$
) AS ct ("Section" text, "Active" int, "Inactive" int);
戻り値:
セクション| アクティブ| 非活性
--------- + -------- + ----------
A | 1 | 2
B | 4 | 5
C | | 7- !!
の正しい結果に注意してくださいC
。
第2のパラメータは 1つのを返し、任意のクエリとすることができる行の終わりに列定義の順序に一致する属性ごと。次のように、基礎となるテーブルから個別の属性をクエリすることがよくあります。
'SELECT DISTINCT attribute FROM tbl ORDER BY 1'
それはマニュアルにあります。
とにかく(定義済みのバリアントを除いて)列定義リストのすべての列を入力する必要があるため、次の例のような式で短いリストを指定する方が効率的です。crosstabN()
VALUES
$$VALUES ('Active'::text), ('Inactive')$$)
または(マニュアルにはありません):
$$SELECT unnest('{Active,Inactive}'::text[])$$ -- short syntax for long lists
見積りを簡単にするために、ドル見積りを使用しました。
あなたとのことさえでき、出力列の異なるデータ型を持つcrosstab(text, text)
- long値列のテキスト表現は、ターゲット・タイプの有効な入力であるとして。あなたが持つかもしれない。この方法では、さまざまな種類と出力の属性text
、date
、numeric
それぞれの属性についてなど。マニュアルの章crosstab(text, text)
の最後にコード例があります。
ここに db <> fiddle
高度な例
\crosstabview
PSQLで
Postgres 9.6は、このメタコマンドをデフォルトのインタラクティブターミナルpsqlに追加しました。最初のcrosstab()
パラメーターとして使用するクエリを実行し、それを\crosstabview
(すぐにまたは次のステップで)にフィードできます。お気に入り:
db=> SELECT section, status, ct FROM tbl \crosstabview
上記と同様の結果ですが、これはクライアント側の排他的な表現機能です。入力行は少し異なる方法で処理されるため、ORDER BY
必要ありません。\crosstabview
マニュアルの詳細。そのページの下部には、さらに多くのコード例があります。
DanielVérité(psql機能の作者)によるdba.SEの関連回答:
以前に受け入れられた答えは時代遅れです。
関数のバリアントcrosstab(text, integer)
が古くなっています。2番目のinteger
パラメーターは無視されます。私は現在のマニュアルを引用します:
crosstab(text sql, int N)
...
の廃止バージョンcrosstab(text)
。N
値列の数は常に呼び出し元のクエリによって決定されるため、パラメーターは無視されます。
不必要なキャストと名前の変更。
行にすべての属性がない場合は失敗します。不足している属性を適切に処理するには、上記の2つの入力パラメーターを持つ安全なバリアントを参照してください。
ORDER BY
の1パラメータ形式では必須ですcrosstab()
。マニュアル:
実際には、SQLクエリは常にORDER BY 1,2
入力行が適切に順序付けられるように指定する必要があります