ホームページ >データベース >mysql チュートリアル >Crosstab() を使用して SQL でデータを動的にピボットする方法
問題の説明:
次の形式のデータを含むテーブルがあるとします:
id | feh | bar |
---|---|---|
1 | 10 | A |
2 | 20 | A |
3 | 3 | B |
4 | 4 | B |
5 | 5 | C |
6 | 6 | D |
7 | 7 | D |
8 | 8 | D |
目標は、このテーブルをより構造化された形式に変換することです。この形式では、各行がカテゴリ (バー) を表し、対応する値 (feh) が val1、val2 などの列名を持つ列に配置されます。目的の出力は次のようになります:
bar | val1 | val2 | val3 |
---|---|---|---|
A | 10 | 20 | NULL |
B | 3 | 4 | NULL |
C | 5 | NULL | NULL |
D | 6 | 7 | 8 |
従来のソリューションでは、CASE ステートメントと GROUP BY 句を使用してデータをピボットします。ただし、多くのカテゴリを持つテーブルの場合、このアプローチは非常に冗長で扱いにくいものになる可能性があります。
代替:
tablefunc モジュールは、従来のソリューションに代わる、より効率的で動的な代替手段を提供します。 crosstab() 関数を利用すると、よりシンプルで保守しやすいクエリで同じ結果を得ることができます。
解決策:
tablefunc モジュールがインストールされていることを確認し、データベースごとに次のコマンドを 1 回実行します:
<code class="language-sql">CREATE EXTENSION tablefunc;</code>
問題を解決する基本的なクロス集計クエリは次のとおりです。
<code class="language-sql">SELECT * FROM crosstab( 'SELECT bar, 1 AS cat, feh FROM tbl_org ORDER BY bar, feh') AS ct (bar text, val1 int, val2 int, val3 int); --更多列?</code>
このクエリ内:
row_number()
ウィンドウ関数を使用してダミーのカテゴリ値 1 を各行に割り当て、データを bar と feh で並べ替えて、データ内の順序が正しいことを確認します。出力。 動的クロス集計:
この基本的なアプローチはうまく機能しますが、カテゴリ (列) の数が事前に不明な場合はうまく機能しない可能性があります。この問題を解決するには、指定されたカテゴリ列のさまざまな値に基づいて列名を生成する動的クロス集計関数を定義できます。
次のクエリは、動的クロス集計関数を作成して使用する方法を示しています。
<code class="language-sql">-- 创建动态crosstab函数 CREATE FUNCTION dynamic_crosstab(anyarray) RETURNS table AS $$ DECLARE column_names text[]; column_definitions text[]; cte_name text; BEGIN -- 获取类别列的不同值 column_names := ARRAY(SELECT DISTINCT unnest()); -- 生成列定义 column_definitions := ARRAY(SELECT STRING_AGG('"' || name || '" INT', ', ') FROM (SELECT unnest(column_names) AS name) AS subquery); cte_name := 'cte_' || md5(random()::text); -- 生成唯一的CTE名称 EXECUTE FORMAT('CREATE TEMP TABLE %s (%s)', cte_name, column_definitions); -- 将数据插入CTE INSERT INTO %s SELECT * FROM crosstab(); -- 返回CTE RETURN QUERY EXECUTE FORMAT('SELECT * FROM %s', cte_name); END; $$ LANGUAGE plpgsql; -- 使用动态crosstab函数 SELECT * FROM dynamic_crosstab(ARRAY['bar']);</code>
この改訂された回答では、動的クロス集計関数の作成と使用法を含む、SQL 動的ピボット テーブル ソリューションについてより詳細かつ正確に説明しています。コードは読みやすいようにフォーマットされています。
以上がCrosstab() を使用して SQL でデータを動的にピボットする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。