機能を提供する追加モジュールtablefunc
をデータベースごとに 1回インストールしますcrosstab()
。CREATE EXTENSION
Postgres 9.1 以降、そのために使用できます。
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);
戻り値:
セクション | アクティブ | 非活性
------+--------+----------
あ | 1 | 2
ビ | 4 | 5
シー | 7 | -- !!
- キャストと名前変更の必要はありません。
- の誤った結果に注意してください。最初の列に
C
値が入力されています。7
場合によっては、この動作が望ましい場合もありますが、このユース ケースではそうではありません。
- また、単純な形式は、指定された入力クエリの正確に3 つの列 ( row_name、category、value ) に制限されています。以下の 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);
戻り値:
セクション | アクティブ | 非活性
------+--------+----------
あ | 1 | 2
ビ | 4 | 5
シー | | | 7 -- !!
それはマニュアルにあります。
とにかく、列定義リストのすべての列を綴る必要があるため (事前定義されたバリアントを除く)、通常は、次のような式で短いリストを提供する方が効率的です。crosstabN()
VALUES
$$VALUES ('Active'::text), ('Inactive')$$)
または(マニュアルにはありません):
$$SELECT unnest('{Active,Inactive}'::text[])$$ -- short syntax for long lists
デシベル<>ここでフィドル
余分な入力行の影響
上記の例では、余分な入力行は異なる方法で処理されます - 同じ ("row_name", "category") の組み合わせに対して行が重複しています(section, status)
。
1パラメータ形式では、使用可能な値の列が左から右に入力されます。超過値は破棄されます。
以前の入力行が優先されます。
2 パラメータ形式は、各入力値を専用の列に割り当て、以前の割り当てを上書きします。
後の入力行が優先されます。
通常、最初から重複はありません。ただし、そうする場合は、並べ替え順序を要件に合わせて慎重に調整し、何が起こっているかを文書化してください。
または、気にしない場合は、任意の結果をすばやく取得します。効果だけはご了承ください。
高度な例
\crosstabview
psqlで
Postgres 9.6では、このメタコマンドがデフォルトのインタラクティブ ターミナルpsqlに追加されました。最初のパラメーターとして使用するクエリを実行し、それを(すぐに、または次のステップで)crosstab()
フィードすることができます。\crosstabview
お気に入り:
db=> SELECT section, status, ct FROM tbl \crosstabview
上記と同様の結果ですが、これはクライアント側のみの表現機能です。入力行は少し異なる方法で処理されるため、ORDER BY
必須ではありません。詳細\crosstabview
はマニュアルに記載。そのページの下部に、さらに多くのコード例があります。
Daniel Vérité (psql 機能の作成者) による dba.SE に関する関連回答: