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

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

新規登録して質問してみよう
ただいま回答率
85.48%
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回答

3167閲覧

ログテーブルから集計テーブルを作成したい

HRS_O

総合スコア70

MySQL

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

SQL

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

0グッド

0クリップ

投稿2017/07/14 12:49

前提・実現したいこと

  • MySQL5.6

ログテーブルの各codeについて出現位置(1〜4)ごとの出現回数と利用ユーザー数を集計し、集計テーブルの様な形に落とし込みたい

ログテーブル

|id|user_id|code1|code2|code3|code4|
|--|--|
|1|1|100001|100002|100003|100004|
|2|1|100003|100002|100005|100004|
|3|2|100004|100002|100003|100001|
|4|4|100004|100001|100003|100002|
|5|6|100005|100002|100003|100004|
|6|2|100001|100002|100003|100004|

sql

1CREATE TABLE `log` ( 2 `id` int(11) NOT NULL, 3 `user_id` int(11) DEFAULT NULL, 4 `code1` int(11) DEFAULT NULL, 5 `code2` int(11) DEFAULT NULL, 6 `code3` int(11) DEFAULT NULL, 7 `code4` int(11) DEFAULT NULL, 8 PRIMARY KEY (`id`) 9) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

(定義は簡略化してます)

集計テーブル

|code|first_count|first_user_count|second_count|second_user_count|third_count|third_user_count|fourth_count|fourth_user_count|
|--|--|
|100001|2|2|1|1|0|0|1|1|
|100002|0|0|5|3|0|0|1|1|
|100003|1|1|0|0|5|4|0|0|
|100004|2|2|0|0|0|0|4|3|
|100005|1|1|0|0|1|1|0|0|

sql

1CREATE TABLE `summary` ( 2 `code` int(11) NOT NULL, 3 `first_count` int(11) DEFAULT NULL, 4 `first_user_count` int(11) DEFAULT NULL, 5 `second_count` int(11) DEFAULT NULL, 6 `second_user_count` int(11) DEFAULT NULL, 7 `third_count` int(11) DEFAULT NULL, 8 `third_user_count` int(11) DEFAULT NULL, 9 `fourth_count` int(11) DEFAULT NULL, 10 `fourth_user_count` int(11) DEFAULT NULL, 11 PRIMARY KEY (`code`) 12) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 13

(定義は簡略化してます)

試したこと・困っていること

1−4それぞれに関しては下記の様なクエリを4つ書けば取れそうなのですが(3,4は省略)
これを1テーブルに落とし込むのに難儀しております。
最終的にはselect insertのような形にしたいと思っており、難しいようであればそれぞれselectしてスクリプトで処理するかなという感じではあるのですが何かいいアイディアはありませんでしょうか。

  • 1番目に出現したデータの集計

sql

1SELECT 2 code1, 3 COUNT(*) as first_count, 4 COUNT(DISTINCT user_id) as first_user_count 5FROM 6 log 7GROUP BY code1;

|code|first_count|first_user_count|
|--|--|
|100001|2|2|
|100003|1|1|
|100004|2|2|
|100005|1|1|

  • 2番目に出現したデータの集計

sql

1SELECT 2 code2, 3 COUNT(*) as second_count, 4 COUNT(DISTINCT user_id) as second_user_count 5FROM 6 log 7GROUP BY code2;

|code|second_count|second_user_count|
|--|--|
|100001|1|1|
|100002|5|3|

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

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

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

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

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

guest

回答2

0

ご参考程度ですが作成してみました。

sql

1insert into `summary` 2select t3.code1, 3t3.c1, t4.u1, t3.c2, t4.u2, t3.c3, t4.u3, t3.c4, t4.u4 4from 5 (select t1.code1 6 ,count(case rw when 1 then 1 else null end) c1 7 ,count(case rw when 2 then 1 else null end) c2 8 ,count(case rw when 3 then 1 else null end) c3 9 ,count(case rw when 4 then 1 else null end) c4 10 from ( 11 select code1, user_id, 1 rw from `log` 12 union all select code2, user_id, 2 from `log` 13 union all select code3, user_id, 3 from `log` 14 union all select code4, user_id, 4 from `log` 15 ) t1 group by 1 16 ) t3 join 17 (select t1.code1 18 ,count(case rw when 1 then 1 else null end) u1 19 ,count(case rw when 2 then 1 else null end) u2 20 ,count(case rw when 3 then 1 else null end) u3 21 ,count(case rw when 4 then 1 else null end) u4 22 from ( 23 select distinct code1, user_id, 1 rw from `log` 24 union all select distinct code2, user_id, 2 from `log` 25 union all select distinct code3, user_id, 3 from `log` 26 union all select distinct code4, user_id, 4 from `log` 27 ) t1 group by 1 28 ) t4 on t3.code1=t4.code1 29;

投稿2017/08/06 03:17

A.Ichi

総合スコア4070

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

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

0

ベストアンサー

細かい事は言語の中のコメントへ。

SQL

1-- データ登録 2INSERT INTO log VALUES 3 (1, 1, 100001, 100002, 100003, 100004) 4,(2, 1, 100003, 100002, 100005, 100004) 5,(3, 2, 100004, 100002, 100003, 100001) 6,(4, 4, 100004, 100001, 100003, 100002) 7,(5, 6, 100005, 100002, 100003, 100004) 8,(6, 2, 100001, 100002, 100003, 100004); 9 10-- 性能問題のためのおまじない。データ量が少量であれば、実行不要。 11-- ALTER TABLE log 12-- ADD INDEX IX_log_1( code1, user_id ) 13-- ,ADD INDEX IX_log_2( code2, user_id ) 14-- ,ADD INDEX IX_log_3( code3, user_id ) 15-- ,ADD INDEX IX_log_4( code4, user_id ); 16-- 17 18-- SELECT INSERT 前に前のデータを削除。 19-- TRUNCATEに抵抗があり、logテーブルのデータが更新型でなければ、TRUNCATE & INSERT INTO ではなく、REPLACE INTO SELECTでも可。 20TRUNCATE TABLE summary; 21 22-- SELECT INSERT 文。 23INSERT INTO summary 24SELECT T1.code 25 , ( 26 SELECT COUNT('X') 27 FROM log T2 28 WHERE T2.code1 = T1.code 29 ) as code1_cnt 30 , ( 31 SELECT COUNT( distinct T3.user_id ) 32 FROM log T3 33 WHERE T3.code1 = T1.code 34 ) as code1_user_cnt 35 , ( 36 SELECT COUNT('X') 37 FROM log T4 38 WHERE T4.code2 = T1.code 39 ) as code2_cnt 40 , ( 41 SELECT COUNT( distinct T5.user_id ) 42 FROM log T5 43 WHERE T5.code2 = T1.code 44 ) as code2_user_cnt 45 , ( 46 SELECT COUNT('X') 47 FROM log T6 48 WHERE T6.code3 = T1.code 49 ) as code3_cnt 50 , ( 51 SELECT COUNT( distinct T7.user_id ) 52 FROM log T7 53 WHERE T7.code3 = T1.code 54 ) as code3_user_cnt 55 , ( 56 SELECT COUNT('X') 57 FROM log T8 58 WHERE T8.code4 = T1.code 59 ) as code4_cnt 60 , ( 61 SELECT COUNT( distinct T8.user_id ) 62 FROM log T8 63 WHERE T8.code4 = T1.code 64 ) as code4_user_cnt 65FROM ( 66 SELECT distinct code1 as code FROM log 67 UNION SELECT distinct code2 as code FROM log 68 UNION SELECT distinct code3 as code FROM log 69 UNION SELECT distinct code4 as code FROM log 70 ) T1 71; 72 73-- 抽出SQL 74select * from summary;

投稿2017/07/14 13:24

編集2017/07/14 13:27
tomari_perform

総合スコア760

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

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

HRS_O

2017/07/15 10:56

回答ありがとうございます、やはりそれぞれごとでselectする形になるようですが実現出来ました。 100万件ほど抽出出来る状態(テーブル自体は1000万ほど投入)で90秒強でした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問