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

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

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

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Q&A

解決済

2回答

3199閲覧

1つまたは2つ以上前のレコードのデータ内容を反映させたい。

miyu21

総合スコア111

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

0グッド

0クリップ

投稿2017/06/15 21:15

###前提・実現したいこと
PostgreSQLを使用しています。
ウィンドウ関数を使うなどして、以下のことを実現させたいです。

testテーブルを読み込み、以下のことをしたいです。
・col1の昇順に並べ替える。
・col2='A',col3='0'のデータがあったら、そのcol1の値を、
次またはそれ以降のレコードが「col3='1'の間のみ」
次またはそれ以降のレコードに編集する。

###データ
元データが「test」テーブル。
testテーブルから抽出したいデータは「test2」テーブルと同内容です。

insert文にコメントが書いてあるレコードについて
testテーブル:処理に関係のある条件が書いてあります
test2テーブル:col4に編集したい内容が書いてあります

-- test1:元データのテーブル create table test( col1 integer, col2 char(1), col3 char(1) ); insert into test values(1,'B','0'); insert into test values(2,'A','0'); -- [1] col2='A',col3='0' insert into test values(3,'B','1'); -- [2] col3='1' insert into test values(4,'B','0'); insert into test values(5,'B','1'); insert into test values(6,'A','0'); -- [3] col2='A',col3='0' insert into test values(7,'C','1'); -- [4] col3='1' insert into test values(8,'C','1'); -- [5] col3='1' insert into test values(9,'D','1'); -- [6] col3='1' insert into test values(10,'B','0'); select * from test order by col1; -- test2:testテーブルから抽出したい内容と同内容のテーブル create table test2( col1 integer, col2 char(1), col3 char(1), col4 integer ); insert into test2 values(1,'B','0',null); insert into test2 values(2,'A','0',null); -- [1] insert into test2 values(3,'B','1',2); -- [2] col4 = [1]のcol1 insert into test2 values(4,'B','0',null); insert into test2 values(5,'B','1',null); insert into test2 values(6,'A','0',null); -- [3] insert into test2 values(7,'C','1',6); -- [4] col4 = [3]のcol1 insert into test2 values(8,'C','1',6); -- [5] col4 = [3]のcol1 insert into test2 values(9,'D','1',6); -- [6] col4 = [3]のcol1 insert into test2 values(10,'B','0',null); select * from test2 order by col1;

試したこと

lag関数を使うなどやってみたのですが、
単純に前のレコードの値が欲しいわけではないので、
できませんでした。

どうぞよろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

withを使いました。

sql

1WITH RECURSIVE r AS ( 2 SELECT *, NULL::int col4 FROM test WHERE col1 = 1 3 UNION ALL 4 SELECT test.*, 5 case when test.col3='1' AND r.col2='A' AND r.col3='0' then r.col1 6 when test.col3='1' AND r.col4 is NOT NULL then r.col4 7 else null end 8 FROM test, r WHERE test.col1 = r.col1+1 9) 10SELECT * FROM r ORDER BY 1; 11

投稿2017/06/15 22:47

A.Ichi

総合スコア4070

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

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

miyu21

2017/06/15 22:59

早速のご回答、ありがとうございます。 再帰は、試しに実行しただけで、きちんと使ったことがありませんでした。 今日中には実行し、結果を書き込ませていただきます。 引き続き、どうぞよろしくお願いいたします。
miyu21

2017/06/16 12:57

おかげさまで、無事に実行することができました。 自分のやりたい内容に適用することもできましたので、 活用していきたいと思います。 コードを書いてくださったA.Ichi様、 今後のヒントにもなる回答をくださったdojikko様、 本当にありがとうございました。
guest

0

カーソルが使えるなら、ちまちまやる
いろいろ後出しで条件が出てきそうなので、外(JavaでもPHPでも)でループ回して処理するとかはダメですか

結局、不定数の複数のレコードを参照しながら処理しなければならないようなので、むしろ外でやった方がパフォーマンスはよいかもしれません

投稿2017/06/15 21:29

dojikko

総合スコア3939

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

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

miyu21

2017/06/15 21:38

早速のご回答、ありがとうございます。 ・カーソルは使ったことがなく、また、カーソルは使えない環境です。 ・Pythonは少しできるのですが、今回のようなことがすぐにできるほどの  スキルがありません。 ・後出しの条件は出てきません。  (これだけができれば、後のことはできます。  それを説明すると話がややこしくなるので、割愛させていただきました。) ・パフォーマンスは低くて構いません。(処理件数は数万件レベル。) やはり、これをやるには無理があるでしょうか。 どなたか、なんとか助けていただけると幸いです。 どうぞよろしくお願いいたします。
dojikko

2017/06/15 21:44 編集

「後出しで条件が出てきそう」ってのは悪い意味(QAサイト的な)ではなく、後々に集計の条件(ロジック)が変わるという意味です 気分を害されたらすみません
miyu21

2017/06/15 21:51

お気を遣わせてしまって申し訳ありません。 そのような受け取り方をしたわけではなく、 「とにかく、通常のSQLだけでなんとかできないものか」と 必死になっておりました。 ご回答、感謝しております。 引き続き、何かありましたらよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問