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

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

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

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

Q&A

解決済

2回答

479閲覧

MySQL の SQL 文がわからない(from句でのネスト)

invoke_zard

総合スコア7

MySQL

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

0グッド

0クリップ

投稿2017/10/27 10:27

###前提・実現したいこと
ここに質問したいことを詳細に書いてください
(例)PHP(CakePHP)で●●なシステムを作っています。
■■な機能を実装中に以下のエラーメッセージが発生しました。

###発生している問題・エラーメッセージ

エラーメッセージ

###該当のソースコード

ここにご自身が実行したソースコードを書いてください

###試したこと
課題に対してアプローチしたことを記載してください

###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報
###前提・実現したいこと
Seasar2 を用いて、Web 開発をしております。
SQLファイルを作成し SQL を実行する形なのですが、
以下の SQL がうまく実行されません。

select文の from句でのサブクエリ?ネスト?が
あまり自信ありません。
少しでも気になった点があれば、教えてください。
よろしくお願いします。

なお、データベースは MySQL を用いています。

###発生している問題・エラーメッセージ

SQL が実行されたきり、応答がない。(フリーズ) おそらく、SQL 文が不正なため。

###該当のソースコード

MySQL

1select 2 a.name 3 ,a.grp_cd 4 ,'1' as kaiso 5 ,a.oya_grp_cd 6 ,coalesce(b.cnt, 0) + coalesce(d.cnt, 0) 7 ,(coalesce(b.cnt, 0) + coalesce(d.cnt, 0)) as oya_cnt 8from ( 9 select 10 '全国' as name 11 ,'001' as grp_cd 12 ,'' as oya_grp_cd 13 from amc.t_shop s 14 group by grp_cd 15) as a 16 left join ( 17 select 18 count(*) as cnt, 19 '001' as grp_cd 20 from ( 21 select 22 ttd.server_code as server_code, 23 ttd.item1 as item1 24 from region.t_tatemono_data ttd 25 where date_format(ttd.item108, '%Y-%m-%d') between /*startYmd_alert*/'2017-10-01' and /*endYmd_alert*/'2017-10-31' 26 ) as abc 27 left join region.opt_approach_info oa 28 on oa.server_code=abc.server_code and oa.tatemono_code=abc.item1 and oa.charge_shop_code <> '000PAR' 29 left join region.opt_visit_history ov 30 on ov.id = oa.last_visit_history_id 31 )as b on a.grp_cd = b.grp_cd 32 33 left join ( 34 select 35 count(*) as cnt, 36 '001' as grp_cd 37 from ( 38 select 39 ob.id as id 40 from region.opt_building ob 41 where date_format(ob.regist_date, '%Y-%m-%d') between /*startYmd_alert*/'2017-10-01' and /*endYmd_alert*/'2017-10-31' 42 ) as abc 43 left join region.opt_approach_info oa 44 on oa.opt_building_id=abc.id and oa.charge_shop_code <> '000PAR' 45 left join region.opt_visit_history ov 46 on ov.id = oa.last_visit_history_id 47 )as d on a.grp_cd = d.grp_cd 48order by grp_cd

###試したこと
課題に対してアプローチしたことを記載してください

###補足情報(言語/FW/ツール等のバージョンなど)
Seasar2
Java
eclipse
###前提・実現したいこと
Seasar2 を用いて、Web 開発をしております。
SQLファイルを作成し SQL を実行する形なのですが、
以下の SQL がうまく実行されません。

select文の from句でのサブクエリ?ネスト?が
あまり自信ありません。
少しでも気になった点があれば、教えてください。
よろしくお願いします。

なお、データベースは MySQL を用いています。

###発生している問題・エラーメッセージ

SQL が実行されたきり、応答がない。(フリーズ) おそらく、SQL 文が不正なため。

###該当のソースコード

MySQL

1select 2 a.name 3 ,a.grp_cd 4 ,'1' as kaiso 5 ,a.oya_grp_cd 6 ,coalesce(b.cnt, 0) + coalesce(d.cnt, 0) 7 ,(coalesce(b.cnt, 0) + coalesce(d.cnt, 0)) as oya_cnt 8from ( 9 select 10 '全国' as name 11 ,'001' as grp_cd 12 ,'' as oya_grp_cd 13 from amc.t_shop s 14 group by grp_cd 15) as a 16 left join ( 17 select 18 count(*) as cnt, 19 '001' as grp_cd 20 from ( 21 select 22 ttd.server_code as server_code, 23 ttd.item1 as item1 24 from region.t_tatemono_data ttd 25 where date_format(ttd.item108, '%Y-%m-%d') between /*startYmd_alert*/'2017-10-01' and /*endYmd_alert*/'2017-10-31' 26 ) as abc 27 left join region.opt_approach_info oa 28 on oa.server_code=abc.server_code and oa.tatemono_code=abc.item1 and oa.charge_shop_code <> '000PAR' 29 left join region.opt_visit_history ov 30 on ov.id = oa.last_visit_history_id 31 )as b on a.grp_cd = b.grp_cd 32 33 left join ( 34 select 35 count(*) as cnt, 36 '001' as grp_cd 37 from ( 38 select 39 ob.id as id 40 from region.opt_building ob 41 where date_format(ob.regist_date, '%Y-%m-%d') between /*startYmd_alert*/'2017-10-01' and /*endYmd_alert*/'2017-10-31' 42 ) as abc 43 left join region.opt_approach_info oa 44 on oa.opt_building_id=abc.id and oa.charge_shop_code <> '000PAR' 45 left join region.opt_visit_history ov 46 on ov.id = oa.last_visit_history_id 47 )as d on a.grp_cd = d.grp_cd 48order by grp_cd

###試したこと
課題に対してアプローチしたことを記載してください

###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報
###前提・実現したいこと
Seasar2 を用いて、Web 開発をしております。
SQLファイルを作成し SQL を実行する形なのですが、
以下の SQL がうまく実行されません。

select文の from句でのサブクエリ?ネスト?が
あまり自信ありません。
少しでも気になった点があれば、教えてください。
よろしくお願いします。

なお、データベースは MySQL を用いています。

###発生している問題・エラーメッセージ

SQL が実行されたきり、応答がない。(フリーズ) おそらく、SQL 文が不正なため。

###該当のソースコード

MySQL

1select 2 a.name 3 ,a.grp_cd 4 ,'1' as kaiso 5 ,a.oya_grp_cd 6 ,coalesce(b.cnt, 0) + coalesce(d.cnt, 0) 7 ,(coalesce(b.cnt, 0) + coalesce(d.cnt, 0)) as oya_cnt 8from ( 9 select 10 '全国' as name 11 ,'001' as grp_cd 12 ,'' as oya_grp_cd 13 from amc.t_shop s 14 group by grp_cd 15) as a 16 left join ( 17 select 18 count(*) as cnt, 19 '001' as grp_cd 20 from ( 21 select 22 ttd.server_code as server_code, 23 ttd.item1 as item1 24 from region.t_tatemono_data ttd 25 where date_format(ttd.item108, '%Y-%m-%d') between /*startYmd_alert*/'2017-10-01' and /*endYmd_alert*/'2017-10-31' 26 ) as abc 27 left join region.opt_approach_info oa 28 on oa.server_code=abc.server_code and oa.tatemono_code=abc.item1 and oa.charge_shop_code <> '000PAR' 29 left join region.opt_visit_history ov 30 on ov.id = oa.last_visit_history_id 31 )as b on a.grp_cd = b.grp_cd 32 33 left join ( 34 select 35 count(*) as cnt, 36 '001' as grp_cd 37 from ( 38 select 39 ob.id as id 40 from region.opt_building ob 41 where date_format(ob.regist_date, '%Y-%m-%d') between /*startYmd_alert*/'2017-10-01' and /*endYmd_alert*/'2017-10-31' 42 ) as abc 43 left join region.opt_approach_info oa 44 on oa.opt_building_id=abc.id and oa.charge_shop_code <> '000PAR' 45 left join region.opt_visit_history ov 46 on ov.id = oa.last_visit_history_id 47 )as d on a.grp_cd = d.grp_cd 48order by grp_cd

###試したこと
課題に対してアプローチしたことを記載してください

###補足情報(言語/FW/ツール等のバージョンなど)
Seasar2
Java
eclipse

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

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

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

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

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

guest

回答2

0

このくらいネストしているのは回答者の環境で再現させることは相当こんなんです。
どうしてもというならcreate table ~ insert intoで
テーブルのサンプルを提示してもらう必要があるでしょう。

とりあえずできそうなことは最小単位になっているサブクエリからEXPLAINでインデックスが
適正にはられているかチェックすることでしょうか。
left joinを多用しているところをみると、正規化したデータとは別のリレーションを
しているように見受けられるので集計データが累乗的なサイズになっているのかもしれません

投稿2017/10/27 11:39

yambejp

総合スコア114583

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

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

invoke_zard

2017/10/29 23:48

ズバリ適格なアドバイス、ありがとうございます。 おっしゃる通りでした・・・。 EXPALINって便利ですね!今まで存在を知りませんでした(⌒∇⌒)
guest

0

ベストアンサー

SQL が実行されたきり、応答がない。(フリーズ)
おそらく、SQL 文が不正なため。

不正なら速攻でエラーが返ってきます。処理に時間が掛かっているんでしょう。
処理時間が遅いため試行錯誤の末、ネストさせてみたというところでしょうか。

意味不明なところが見受けられますが、取り敢えずは日付の抽出条件のところを修正した方が良いですね。

SQL

1where ttd.item108 between str_to_date(/*startYmd_alert*/'2017-10-01', '%Y-%m-%d') 2 and str_to_date(/*endYmd_alert*/'2017-10-31', '%Y-%m-%d') 3 4where ob.regist_date between str_to_date(/*startYmd_alert*/'2017-10-01', '%Y-%m-%d') 5 and str_to_date(/*endYmd_alert*/'2017-10-31', '%Y-%m-%d')

item108 や regist_date がインデックスに含まれるなら、効果が望めます。
普段から、条件部分の記述にDB項目自体を演算しない癖をつけていた方がいいですよ。
チューニングでインデックス追加するような場合でも、手直しは不要になりますから。

追記

意味不明なところを確認してみましょう。

SQL

1select 2 count(*) as cnt, 3 '001' as grp_cd 4from ( 5 select 6 ttd.server_code as server_code, 7 ttd.item1 as item1 8 from region.t_tatemono_data ttd 9 where date_format(ttd.item108, '%Y-%m-%d') between /*startYmd_alert*/'2017-10-01' and /*endYmd_alert*/'2017-10-31' 10 ) as abc 11 left join region.opt_approach_info oa 12 on oa.server_code=abc.server_code and oa.tatemono_code=abc.item1 and oa.charge_shop_code <> '000PAR' 13 left join region.opt_visit_history ov 14 on ov.id = oa.last_visit_history_id

ここ、region.opt_approach_inforegion.opt_visit_historyをjoinしてますけど、件数求めるだけならleft joinなので意味がないですね。もう一つも同じです。
それから、駆動表のように記述されている、t_shopでのgroup by も固定値で行ってるので意味ないですね。

単に書かれていることを、join部分をinnerとして組み立て直すとこんな感じかな。
関係性においてleft joinが正しいなら、そもそもjoinは不要。

SQL

1select 2 '全国' as name 3 , '001' as grp_cd 4 , '1' as kaiso 5 , '' as oya_grp_cd 6 , coalesce(( 7 select count(*) 8 from region.t_tatemono_data ttd 9 inner join region.opt_approach_info oa 10 on oa.server_code=ttd.server_code and oa.tatemono_code=ttd.item1 11 and oa.charge_shop_code <> '000PAR' 12 inner join region.opt_visit_history ov 13 on ov.id = oa.last_visit_history_id 14 where ttd.item108 between str_to_date(/*startYmd_alert*/'2017-10-01', '%Y-%m-%d') 15 and str_to_date(/*endYmd_alert*/'2017-10-31', '%Y-%m-%d') 16 ), 0) + coalesce(( 17 select count(*) 18 from region.opt_building ob 19 inner join region.opt_approach_info oa 20 on oa.opt_building_id=ob.id and oa.charge_shop_code <> '000PAR' 21 inner join region.opt_visit_history ov 22 on ov.id = oa.last_visit_history_id 23 where ob.regist_date between str_to_date(/*startYmd_alert*/'2017-10-01', '%Y-%m-%d') 24 and str_to_date(/*endYmd_alert*/'2017-10-31', '%Y-%m-%d') 25 ), 0) as oya_cnt

何にしても、実行計画でパフォーマンスは確認された方がよいかと思います。

投稿2017/10/27 11:27

編集2017/10/28 00:55
sazi

総合スコア25138

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

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

invoke_zard

2017/10/27 11:30

回答ありがとうございます! なるほど、日付部分が少しおかしいのですか。 補足的なアドバイスもありがとうございます(^▽^)/ 実行して、気長に待ってみることにします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問