ホームページ >データベース >mysql チュートリアル >Crosstab() を使用して SQL でデータを動的にピボットする方法

Crosstab() を使用して SQL でデータを動的にピボットする方法

Patricia Arquette
Patricia Arquetteオリジナル
2025-01-20 22:17:09173ブラウズ

SQL 動的ピボット テーブル:crosstab() 関数を使用した動的代替手段

How to Dynamically Pivot Data in SQL Using crosstab()?

問題の説明:

次の形式のデータを含むテーブルがあるとします:

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>

このクエリ内:

  • crosstab() 関数は、データを選択して各行にダミーのカテゴリ値を割り当てるサブクエリと、列名のリスト (この場合は val1、val2、および val3) の 2 つのパラメータを受け入れます。
  • サブクエリは、元のテーブルから bar 列と feh 列を選択し、row_number() ウィンドウ関数を使用してダミーのカテゴリ値 1 を各行に割り当て、データを bar と feh で並べ替えて、データ内の順序が正しいことを確認します。出力。
  • crosstab() 関数の結果は、後続の SELECT ステートメントで参照しやすくするために、ct という名前の CTE (共通テーブル式) に割り当てられます。

動的クロス集計:

この基本的なアプローチはうまく機能しますが、カテゴリ (列) の数が事前に不明な場合はうまく機能しない可能性があります。この問題を解決するには、指定されたカテゴリ列のさまざまな値に基づいて列名を生成する動的クロス集計関数を定義できます。

次のクエリは、動的クロス集計関数を作成して使用する方法を示しています。

<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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。