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

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

解決済

3回答

733閲覧

3つのレコードを1つにするSQL

退会済みユーザー

退会済みユーザー

総合スコア0

MySQL

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

SQL

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

0グッド

0クリップ

投稿2018/02/16 15:44

編集2018/02/16 16:42

現在、社内の部品採番台帳をAccessからMySQLに移行する作業をしています。
Accessの約6万件のデータをMySQLのワークテーブルに入れ込みました。

現在の部品台帳のワークテーブルは以下のようになっています。
|CODE|KEYCODE|CATEGORY|NAME|備考|
|:--|:--:|--:|
|AA1000-01|AA1000-01|0|抵抗1|特に別管理を必要としないもの|
|BA1000-01|AA1000-01|1|抵抗1|AA1000-01と同じ部品だけど△△管理するもの|
|CA1000-01|AA1000-01|2|抵抗1|AA1000-01と同じ部品だけど○○管理するもの|
|BA1001-01|AA1001-01|1|抵抗2|このようにAAのコードがないものもあります|
|CA1002-01|AA1002-01|2|抵抗3|このようにAAのコードがないものもあります|

これを以下のように1つのレコードにしたいと考えています。
|KEYCODE|CODE-A|CODE-B|CODE-C|NAME|
|:--|:--:|--:|
|AA1000-01|AA1000-01|BA1000-01|CA1000-01|抵抗1|
|AA1001-01|NULL|BA1001-01|NULL|抵抗2|
|AA1002-01|NULL|NULL|CA1002-01|抵抗3|

これを実現するSQL(できる限り実行速度が速いもの)を教えていただけないでしょうか。
自分で考えたサブクエリーで引き当てしようとすると
6万件のデータでは遅くて一向に処理が返ってきませんでした。


実はAccessのデータをCSV(SJIS)に落として
C#で作ったアプリで文字分解してKEYCODE、CATEGORYを作成し
UTF8変換してMYSQLのワークテーブルに入れ込みました。
SQLでスマートにできない場合は、この処理過程でCATEGORY=0のものを1つ1つ先に
テーブルにインサートして、CATEGORY=1のものをKEYCODEで検索してUPDATEして・・・
なければインサートして・・・
という処理も視野に入れていますが、全然スマートじゃない気がして質問しました。

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

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

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

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

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

guest

回答3

0

ピボットテーブルのような処理をしたいのですよね?
以下参考程度に

  • 元データ

SQL

1create table tbl(CODE varchar(10),KEYCODE varchar(10),CATEGORY int,NAME varchar(10),備考 text); 2insert into tbl values 3('AA1000-01','AA1000-01','0','抵抗1','特に別管理を必要としないもの'), 4('BA1000-01','AA1000-01','1','抵抗1','AA1000-01と同じ部品だけど△△管理するもの'), 5('CA1000-01','AA1000-01','2','抵抗1','AA1000-01と同じ部品だけど○○管理するもの'), 6('BA1001-01','AA1001-01','1','抵抗2','このようにAAのコードがないものもあります'), 7('CA1002-01','AA1002-01','2','抵抗3','このようにAAのコードがないものもあります');
  • 集計

SQL

1select KEYCODE 2,group_concat(CASE CATEGORY WHEN 0 THEN CODE END) AS CODE_A 3,group_concat(CASE CATEGORY WHEN 1 THEN CODE END) AS CODE_B 4,group_concat(CASE CATEGORY WHEN 2 THEN CODE END) AS CODE_C 5,group_concat(DISTINCT NAME) AS NAME 6from tbl 7group by KEYCODE;

解説

念のため簡単な解説だけつけておきます
今回質問者さんがやろうとしていることはピボットテーブルといって
縦軸のデータを横軸に表示しなおすことです。
具体的なロジックはまずこういうこと

SQL

1select KEYCODE 2,CASE CATEGORY WHEN 0 THEN CODE END AS CODE_A 3,CASE CATEGORY WHEN 1 THEN CODE END AS CODE_B 4,CASE CATEGORY WHEN 2 THEN CODE END AS CODE_C 5,NAME AS NAME 6from tbl;

結果こうなります

|KEYCODE|CODE_A|CODE_B|CODE_C|NAME||
|:--|:--|:--|:--|:--|
|AA1000-01|AA1000-01|NULL|NULL|抵抗1|
|AA1000-01|NULL|BA1000-01|NULL|抵抗1|
|AA1000-01|NULL|NULL|CA1000-01|抵抗1|
|AA1001-01|NULL|BA1001-01|NULL|抵抗2|
|AA1002-01|NULL|NULL|CA1002-01|抵抗3|

これをKEYCODEをキーに縦方向にぐしゃっとつぶします
AA1000-01のCODE_Aは「AA1000-01,null,null」ですから
これをgroup_concatするとnullは無視されて(concat系の処理はnullを無視する)
「AA1000-01」だけになるわけです。CODE_B、CODE_Cについても同様

最後にNAMEについてEYCODEにたいしてNAMEは1対1なので
本来はKEYCODEでgroup byすればNAMEは確定できるはずですが
SQLの文法上許されません。
そのままgroup_concatすると「抵抗1,抵抗1,抵抗1」となってしまいます
これを最初の定義1対1で決まる前提があるのでDISTINCTをすると
複数の抵抗1がひとつにまとまるわけです

本当は、KECODEとNAMEを別テーブルに正規化しておいて集計結果に
JOINするのが本来のSQLの処理です。

ピボットテーブルはデータ管理上の問題なのでデータ出力後
クライアント側で整形処理をする方が効率はよいかもしれません

投稿2018/02/20 13:57

編集2018/02/21 06:57
yambejp

総合スコア114843

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

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

退会済みユーザー

退会済みユーザー

2018/02/21 06:04

group_concat()は知りませんでした。 実行速度もとても速かったです。
guest

0

ベストアンサー

最近のMySQLでは相関サブクエリーでも早くなっていると聞いています。
因みに、ワークテーブルにインデックスは作っていますか?
(KEYCODE,CODE)のインデックスがあれば、相関サブクエリーでもそこそこイケるんじゃないでしょうか?※NAMEもあったほうがより早くなるかも。

因みに相関サブクエリーの場合ってこんな感じかと思いますけど。

SQL

1select keycode 2 ,(select code from tbl where keycode=t.keycode and code like 'A%') as code_a 3 ,(select code from tbl where keycode=t.keycode and code like 'B%') as code_b 4 ,(select code from tbl where keycode=t.keycode and code like 'C%') as code_c 5 , name 6from tbl t 7group by keycode, name

インデックスがある状態で遅いなら、A.Ichiさんの提示されるjoinで結合する方法ですね。
その場合でも、インデックスがあった方が早いと思います。

投稿2018/02/16 18:20

sazi

総合スコア25195

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

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

退会済みユーザー

退会済みユーザー

2018/02/21 06:01

最初にサンプルにしたコードが相関クエリを使ったものでした。 saziさんの仰る通り、インデックスを作ってなかったことが遅かった原因でした。 さらに言うと、サーバマシンにXAMPPをいれて、チューニングしてなかった事も原因でした。
退会済みユーザー

退会済みユーザー

2018/02/21 06:14

A.Ichiさん、saziさん、yambejpさんに教えてもらった方法を チューニングの有無、インデックスの有無で実行させてみました。 ------------------------------------ インデックス        |  なし  |  なし  |  あり  | チューニング        |  なし  |  あり  |  あり  | ------------------------------------ 相関サブクエリ       |*****s|*****s| 4.50s| join          |16.59s|11.80s|10.64s| group_concat  | 4.59s| 3.08s| 1.76s| ------------------------------------ *は300秒以上の為、途中で中断。 結果としてはgroup_concat()が一番早いことがわかりましたが、 今回のそもそもの原因はインデックス貼ってない為だったので ベストアンサーはsaziさんの回答にさせていただきました。
guest

0

6万件のデータでは遅くて一向に処理が返ってきませんでした。

同様なスピードかもしれませんが

sql

1select t1.`KEYCODE`, t2.`CODE` 'CODE-A',t3.`CODE` 'CODE-B',t4.`CODE` 'CODE-C', t1.`NAME` from 2(select distinct `KEYCODE`,`NAME` from `hoge_table`) t1 3left join (select `KEYCODE`,`CODE` from `hoge_table` where `CODE` Like 'AA%') t2 4on t1.`KEYCODE`=t2.`KEYCODE` 5left join (select `KEYCODE`,`CODE` from `hoge_table` where `CODE` Like 'BA%') t3 6on t1.`KEYCODE`=t3.`KEYCODE` 7left join (select `KEYCODE`,`CODE` from `hoge_table` where `CODE` Like 'CA%') t4 8on t1.`KEYCODE`=t4.`KEYCODE` 9order by 1;

投稿2018/02/16 16:37

編集2018/02/16 16:48
A.Ichi

総合スコア4070

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

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

退会済みユーザー

退会済みユーザー

2018/02/16 16:40

ごめんなさい。目的のサンプルが間違ってました。修正します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問