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

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

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

11509閲覧

MySQLでwhileのようなSQLを作りたい

yokatone

総合スコア43

MySQL

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

SQL

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

0グッド

1クリップ

投稿2018/07/13 10:34

編集2018/07/13 10:35

実現したいこと

次のようなテーブルがあったとして

SampleTable

idvalue
1+
2+
3-
4-
5+

次のような処理を持つSQLを作成し

dataset = [+, +, -, -, +] result = [] i = 0 while(flg){ if(dataset[i] == "+"){ result[i] = dataset[i] i++ }else{ flg = false } }

次のような結果を得たいと思っています。

ResultTable

idvalue
1+
2+

(実際のvalueの値は100や-20などの数値ですが、value>0という条件でwhileのようなことをしたいため
便宜的に+, -で表現しています。)

取り組んだこと

条件として、

  • SampleTable.id - 1value-なら表示しない

であればよいので、caseを使って表現できる気がしますが、うまく書けません。
caseでflg列を作り、

ImmidiateTable

idvalueflg
1+true
2+true
3-false
4-false
5+false

となったところで、select * from ImmidiateTable where flg = trueとし、
ResultTableができると思いましたが、

left join (select * from SampleTable as RT where RT.id = SampleTable.id -1) as ReplicaTableで、ReplicaTableに対して
ひとつ前のidのvalueが-ならflg = falseとすると、ちょっとSampleTableからデータが変わってしまいますが

EvaluatedTable

idvalueflg
1-false
2+false
3+true
4-false
5+false

と、愚直に自分のひとつ前のidのSampleTableのvalueを参照し、flgを出力してしまう結果となりました。
つまり、ひとつ前のflgについて評価した自分自身をもう一度評価する必要があって、
(なんていうんでしょうか、original left join original.id -1(SampleTable = original)を横方向に評価し、
次にこの結果自体を縦方向に評価しなければいけない....というか)

( EvaluatedTable ReplicaTable SampleTable EvaluatedTable. id - 1 ReplicaTable SampleTable ) as ResultTable

と、同じ構造を持つクエリが二重に必要になり、可読性、メンテナンス共々に悪すぎます。
考え方自体が間違っている気がしますし、whileのような仕組みがそもそもあればよいのですが
検索しても見つかりません。
スマートに実現できる方法が分かる方、ぜひご教示お願いします。

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

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

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

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

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

sazi

2018/07/13 13:59

MySQLのバージョンは何でしょう?
guest

回答3

0

MySQLのバージョンが8.0以降なら、Window関数(分析関数)が使えます。
MySQL王国に黒船(Window関数)がやってきた!
LAG()やLEAD()を使用すれば比較的容易に取得可能です。

8.0以前であれば、模倣するしかありません。
MySQLで分析関数を模倣3(後編)

投稿2018/07/13 14:10

編集2018/07/13 14:10
sazi

総合スコア25138

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

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

yokatone

2018/07/17 06:20

バージョンは5.6です。 URL参照させていただきましたが、やはりこういう方法を取らざるを得ないんですね。 8.0の情報ありがとうございます。随分と便利になっているみたいですね!
guest

0

ベストアンサー

WHILE を使うにはMySQLではストアドプログラムや他のLOOPできる言語が必要になるので、

SQL

1SELECT ST.id 2 , ST.value 3FROM SampleTable ST 4WHERE ST.id < 5 ( 6 SELECT MIN(ID) AS MIN_ID 7 FROM SampleTable 8 WHERE value = '-' 9 ) ;

はいかが?

投稿2018/07/13 10:54

Orlofsky

総合スコア16415

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

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

yokatone

2018/07/17 06:19

なるほど、条件に合う中での最小(または最大)のidを取って、そこを基準に考えればよかったんですね。 解決しました。どうもありがとうございました!
guest

0

sql

1select id, value from sampletable 2where coalesce( 3 id < (select min(id) from sampletable where value <> '+'), true)

投稿2018/07/13 11:15

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

yokatone

2018/07/17 06:16

こちらでやってみましたが、できませんでした。すみません。。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問