質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

2回答

4846閲覧

SQLの縦持ちデーターの横持変換の方法

primetimefuture

総合スコア46

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2019/05/18 04:22

SQLで縦持ちを横持に変換したいのですが、一般的には以下のような記述でできると思います。(引用です)

しかし今回は、indicatorに入る値が不特定多数です。
下記のSQL文では、indicatorの値をCASE WHENで指定してますが、indicatorの値をSQLで自動で分けてくれるような方法はないのでしょうか?
ちなみにMySQL(MariaDB)で行っております。

どうぞよろしくお願いいたします。

参考URL一部引用
https://book.mynavi.jp/manatee/detail/id=72442

行を列に変換する
最初に、行を列に変換する方法を考えてみましょう。SQLにおける列はクエリによって固定的である必要があるため、列に展開されるデータの種類や数が予め判明している場合にのみ、この手法を利用できます。例えば、下記データ例に示す日次KPIデータは、日付ごとに「インプレッション数」「セッション数」「ユーザー数」の3指標の値を1 レコードごとに保持したテーブルです。

●データ:日次KPIデータ(daily_kpi)テーブル
dt | indicator | val
------------+-------------+------
2017-01-01 | impressions | 1800
2017-01-01 | sessions | 500
2017-01-01 | users | 200
2017-01-02 | impressions | 2000
2017-01-02 | sessions | 700
2017-01-02 | users | 250

求めている結果
dt | impressions | sessions | users
------------+-------------+----------+-------
2017-01-01 | 1800 | 500 | 200
2017-01-02 | 2000 | 700 | 250

●コード:行で保存された指標の値を列に変換するクエリ
これでは、indicatorの値を全部指定してあげないといけない、、

SELECT dt , MAX(CASE WHEN indicator = 'impressions' THEN val END) AS impressions , MAX(CASE WHEN indicator = 'sessions' THEN val END) AS sessions , MAX(CASE WHEN indicator = 'users' THEN val END) AS users FROM daily_kpi GROUP BY dt ORDER BY dt ;

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

こうします

  • 元データ

SQL

1create table daily_kpi(dt date,indicator varchar(20),val int); 2insert into daily_kpi values 3('2017-01-01','impressions',1800), 4('2017-01-01','sessions',500), 5('2017-01-01','users',200), 6('2017-01-02','impressions',2000), 7('2017-01-02','sessions',700), 8('2017-01-02','users',250);
  • 集計

SQL

1select dt 2,sum(val*(indicator='impressions')) as impressions 3,sum(val*(indicator='sessions')) as sessions 4,sum(val*(indicator='users')) as users 5from daily_kpi 6group by dt;

追記

indicatorを別途マスター管理し、表示順を確定すればprocedureを利用できます

  • 元テーブル

SQL

1create table daily_kpi(dt date,id int ,val int); 2insert into daily_kpi values 3('2017-01-01',1,1800), 4('2017-01-01',2,500), 5('2017-01-01',3,200), 6('2017-01-02',1,2000), 7('2017-01-02',2,700), 8('2017-01-02',3,250); 9 10create table indicator(id int primary key,name varchar(20)); 11insert into indicator values 12(1,'impressions'), 13(2,'sessions'), 14(3,'users');
  • procedure作成

SQL

1drop procedure if exists yokogaki; 2delimiter // 3create procedure yokogaki() 4begin 5declare a int; 6declare b varchar(255); 7declare done int default 0; 8declare cur cursor for 9select id,name from indicator order by id; 10declare continue handler for sqlstate '02000' set done=1; 11set @sql='select dt'; 12open cur; 13repeat 14fetch cur into a,b; 15if not done then 16set @sql=CONCAT(@sql,",sum(val*(id=",a,")) as ",b); 17end if; 18until done end repeat; 19close cur; 20set @sql=CONCAT(@sql," from daily_kpi group by dt order by id"); 21prepare stmt from @sql; 22execute stmt; 23end 24// 25delimiter ;
  • 実行

SQL

1 2call yokogaki;

投稿2019/05/20 01:04

編集2019/05/20 07:45
yambejp

総合スコア114883

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

primetimefuture

2019/05/20 07:11

こんなやり方あるのですね、質問とはちょっと違ったのですが試して見たいと思います。参考になりました。
yambejp

2019/05/20 07:46

自動処理にはprocedureを利用すれば一発でできます daily_kpiの値を絞って処理したい場合はyokogakiプロシージャに 引数を渡してフィルタをすることで対応できます
guest

0

ベストアンサー

indicatorの値をSQLで自動で分けてくれるような方法はないのでしょうか?

列数を可変にするという事は、SQLを動的にするしかありません。

動的に行を列に変換するMysqlクエリ

投稿2019/05/18 05:33

sazi

総合スコア25197

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

primetimefuture

2019/05/20 07:10

ありがとうございます。勉強になりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問