0

現在、次の形式のテーブルがあります

account_id | phone_name
0          | samsung M360
12         | HTC One
58         | LG Optimus
12         | Novatel
.            .
.            .
.            .

そして、それを次の形式のテーブルに変換したい

account_id | samsung M360 | HTC One | LG Optimus | Novatel | ...
0            1              0         0            0
12           0              1         0            1
58           0              0         1            0
.
.
.

つまり、それぞれの phone_names の数を含むピボット テーブルを作成したいと考えていますaccount_id。主な問題は、50 以上の異なる電話名があるため、それぞれをリストする通常の方法で MySQL ピボット テーブルを作成できないことですphone_name。これは可能ですか?

4

1 に答える 1

1

MySQL には PIVOT 関数はありませんが、集計関数とCASE式を使用して行を列に変換できます。

数または値が限られている場合はphone_name、クエリをハードコーディングできます。

select account_id,
  sum(case when phone_name = 'samsung M360' then 1 else 0 end) SamsungM360,
  sum(case when phone_name = 'HTC One' then 1 else 0 end) HTCOne,
  sum(case when phone_name = 'LG Optimus' then 1 else 0 end) LGOptimus,
  sum(case when phone_name = 'Novatel' then 1 else 0 end) Novatel
from yt
group by account_id;

SQL Fiddle with Demoを参照してください。

ただし、値が不明になる場合は、準備済みステートメントを使用して動的 SQL を生成する必要があります。

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'sum(CASE WHEN phone_name = ''',
      phone_name,
      ''' THEN 1 else 0 END) AS `',
      phone_name, '`'
    )
  ) INTO @sql
FROM yt;

SET @sql 
  = CONCAT('SELECT account_id, ', @sql, ' 
            from yt
            group by account_id');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SQL Fiddle with Demoを参照してください。両方のクエリの結果は次のとおりです。

| ACCOUNT_ID | SAMSUNG M360 | HTC ONE | LG OPTIMUS | NOVATEL |
--------------------------------------------------------------
|          0 |            1 |       0 |          0 |       0 |
|         12 |            0 |       1 |          0 |       1 |
|         58 |            0 |       0 |          1 |       0 |

注: にGROUP_CONCAT()は、生成される文字列の長さとして 1024 のデフォルト値があります。group_concat_max_lengthその結果、文字列が長すぎる場合は、セッション設定を変更する必要がある場合があります。

于 2013-04-08T14:57:37.190 に答える