実現したいこと
次のようなテーブルがあったとして
SampleTable
| id | value |
|---|---|
| 1 | + |
| 2 | + |
| 3 | - |
| 4 | - |
| 5 | + |
次のような処理を持つSQLを作成し
dataset = [+, +, -, -, +] result = [] i = 0 while(flg){ if(dataset[i] == "+"){ result[i] = dataset[i] i++ }else{ flg = false } }
次のような結果を得たいと思っています。
ResultTable
| id | value |
|---|---|
| 1 | + |
| 2 | + |
(実際のvalueの値は100や-20などの数値ですが、value>0という条件でwhileのようなことをしたいため
便宜的に+, -で表現しています。)
取り組んだこと
条件として、
SampleTable.id - 1のvalueが-なら表示しない
であればよいので、caseを使って表現できる気がしますが、うまく書けません。
caseでflg列を作り、
ImmidiateTable
| id | value | flg |
|---|---|---|
| 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
| id | value | flg |
|---|---|---|
| 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のような仕組みがそもそもあればよいのですが
検索しても見つかりません。
スマートに実現できる方法が分かる方、ぜひご教示お願いします。
回答3件
あなたの回答
tips
プレビュー