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

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

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

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

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

while

Whileは多くの言語で使われるコントロール構造であり、特定の条件が満たされる限り一連の命令を繰り返し実行します。

Q&A

解決済

2回答

2534閲覧

Select句をwhile文を使って作成したい

iiiiiiiikkkk

総合スコア6

MySQL

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

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

while

Whileは多くの言語で使われるコントロール構造であり、特定の条件が満たされる限り一連の命令を繰り返し実行します。

0グッド

0クリップ

投稿2020/06/10 14:26

編集2020/06/11 07:17

前提・実現したいこと

過去に質問され、回答されているコードをMySQLで実行できるように変更したいです。
EXECがMySQL 8.0では動かなかったり、SET QUOTED_IDENTIFIER OFFは存在しなかったりと所々違うので修正できないです。
詳しい方、お願いします。
過去の質問

自分の状況

ちなみに自分は以下のようなコードを上記の回答を見ながらwhile文で作成したいと考えています。
今回は上記の質問への回答のMySQL版がわかればそれを見ながら自分で作業しようと考えています。そのため、自分のコードは一部抜粋で表示しています。

###実装してみた結果
回答いただいた内容をもとに実装しましたが、while文の中のselect文が実行されませんでした。
1つのtemporary tableにデータを収めたい場合はどうすれば良いでしょうか?

MySQL

1DROP TEMPORARY TABLE IF EXISTS tempo_table2; 2DROP PROCEDURE IF EXISTS previous; 3DELIMITER // 4create procedure previous(in p_Limit int) 5Begin 6 SET @sql1 := CONCAT("create temporary table tempo_table2", 7 ' select', 8 ' text_date', 9 ' ,cd_fromName', 10 ' ,cd_text', 11 ' ,command_content', 12 ' ,cd_text_action', 13 ' from tempo_table;'); 14 prepare sql1 FROM @sql1; 15 Execute sql1; 16 Deallocate prepare sql1; 17 SET @CNT = 1; 18 while p_limit >= @CNT Do 19 Set @sql2 := CONCAT("select", 20 ' ,lag(cd_text_action,',@CNT,') over(order by cd_fromName,text_date) as previous_action',@CNT, 21 ' ,lag(cd_fromName,',@CNT,') over(order by cd_fromName,text_date) as previous_Name',@CNT, 22 ' from tempo_table;'); 23 SET @CNT = @CNT + 1; 24 prepare sql2 FROM @sql2; 25 Execute sql2; 26 Deallocate prepare sql2; 27 End while; 28End; 29// 30DELIMITER ; 31call previous(20); 32select * from tempo_table2;

該当のソースコード

lag(cd_text_action,1)
lag(cd_text_action,2)
lag(cd_text_action,3)
のように数字を1つずつ増やしながら、列の作成をしていきたいです。

MySQL

1create temporary table tempo_table2 2select 3 text_date, 4 cd_fromName, 5 cd_text, 6 command_content, 7 cd_text_action, 8 #過去に入力したactionをn回分保存する 9 lag(cd_text_action,1) over(order by cd_fromName,text_date) as previous_action1, 10 lag(cd_text_action,2) over(order by cd_fromName,text_date) as previous_action2,

こちらも同様にprevious_action1,previous_action2,previous_action3

then 1, then 2, then 3のように数字を一つずつ増やしていきたいです。

MySQL

1case 2 when previous_action1 in("menu_cmd_01_01","menu_cmd_02_02") AND cd_fromName = previous_Name1 then 1 3 when previous_action2 in("menu_cmd_01_01","menu_cmd_02_02") AND cd_fromName = previous_Name2 then 2

補足情報(FW/ツールのバージョンなど)

MySQL 8.0

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

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

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

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

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

sazi

2020/06/11 01:03

列を動的に増やすという事は動的SQLの生成になるので、ストアドかフロントのプログラムでSQL文を文字列で組み立てるという事になりますけど、それは理解されていますか?
iiiiiiiikkkk

2020/06/11 01:08

はい、動的SQLの生成になることは理解できています。 ストアドプロシージャでSQL文の文字列を組み立てた上で、プロシージャをcallすることが必要なのではないかと考えています。 しかしながら、私ではプロシージャで組み立てたSQL文をどのように実行すれば良いのかわからないです。 リンク先で言うとEXEC(@sql1+@sql2+,,,)が該当していますが、MySQLではEXECが動作しなかったです。
sazi

2020/06/11 01:18

列をどこまで増やすかは決まっているのですか? 質問のリンク先では24時間という範囲が決まってますけど、この質問では?
iiiiiiiikkkk

2020/06/11 01:25

明確には決めていないのですが、100〜1000の範囲で列を増やしたいと考えています。
guest

回答2

0

saziさんに指摘していただいたミスを修正してみたら動きました!!

MySQL

1DROP TEMPORARY TABLE IF EXISTS tempo_table2; 2DROP PROCEDURE IF EXISTS previous; 3DELIMITER // 4create procedure previous(in p_Limit int) 5Begin 6 SET @sql1 := CONCAT("create temporary table tempo_table2", 7 ' select', 8 ' text_date', 9 ' ,cd_fromName', 10 ' ,cd_text', 11 ' ,command_content', 12 ' ,cd_text_action'); 13 SET @CNT = 1; 14 SET @sql2 := ''; 15 while p_limit >= @CNT Do 16 Set @sql2 := CONCAT(@sql2,' ,lag(cd_text_action,',@CNT,') over(order by cd_fromName,text_date) as previous_action',@CNT, 17 ' ,lag(cd_fromName,',@CNT,') over(order by cd_fromName,text_date) as previous_Name',@CNT); 18 SET @CNT = @CNT + 1; 19 End while; 20 SET @sql3 := CONCAT(@sql1,@sql2,' from tempo_table;'); 21 prepare sql3 FROM @sql3; 22 Execute sql3; 23 Deallocate prepare sql3; 24End; 25// 26DELIMITER ; 27call previous(20); 28select * from tempo_table2;

投稿2020/06/11 08:41

iiiiiiiikkkk

総合スコア6

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

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

0

ベストアンサー

動的SQLについて以下参考
MySQL ストアドプログラム内での動的SQL
MySQLの動的SQL使って検索するカラム名を動的に指定する

ループの終了条件が可変という事なので、先ずは再帰で取得してからの編集が良い気がします。
MySQL 8.0の再帰With句のサンプル集

投稿2020/06/11 01:58

sazi

総合スコア25173

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

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

iiiiiiiikkkk

2020/06/11 07:15

ご回答ありがとございます。動的SQL文の参考URLについて非常に理解しやすかったです。 追加で質問なのですが、 1つ目のURLで示されている手法を一部で実装してみましたが、temporary tableを使用しているためか、while文の中のselect文が実行できません。 コードをアップするのでレビューをいただけないでしょうか?
sazi

2020/06/11 07:27 編集

コード見ましたけど、単に@CNTがカウントアップされて、最後のカウントのSQL文が実行されているだけのように見えます。 ループ内では生成したSQLは上書きされているだけ
iiiiiiiikkkk

2020/06/11 07:23

おそらく行っているとは思います。。。 おっしゃっていることを正確に理解できていないのが正直なところですので、質問本文の「実装してみた結果」のコードを見ていただく事は可能でしょうか? コードはtempo_tableという一時テーブルを作成し、それを読み込んで作業数rものとなっています。 この後にも作業が続くので、tempo_table2として作成したいという状況です。
sazi

2020/06/11 07:29 編集

コメント前後しました。 ループではlagの部分をSQLとして追加するのが、やりたいことではないのでしょうか。
iiiiiiiikkkk

2020/06/11 08:29

はい、その通りです。 なるほど、そのような状況になっていたのですね、、、 どのように改善すればよいか実際のコードで示していただくことは可能でしょうか、、?
iiiiiiiikkkk

2020/06/11 08:40

すみません!おっしゃっていた意味を理解して、自力で修正できました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問