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

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

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

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

SQL

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

Q&A

解決済

2回答

3901閲覧

SQLで抽出した行のひとつ前の行を参照する方法

hideki.

総合スコア31

PostgreSQL

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

SQL

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

0グッド

0クリップ

投稿2021/06/18 06:02

編集2021/06/18 06:24

前提・実現したいこと

以下のようなテーブルがあります。
ptimeカラムはtimestamp型でソートされてます。
(実際は日付時刻のTimestampでユニークです)

ptimecol_acol_b
12:30-10
12:4210
12:44-11
12:5001
12:5201
12:5510
13:00-11

このテーブルからcol_aが-1、かつcol_bが1である行を抽出し、その上の行のptimeカラムを参照して、以下のようなテーブルを作成するSQLを作りたいです。

start_tmend_tm
12:4212:44
12:5513:00

「col_aが-1、かつcol_bが1である行を抽出」は単純なSELECT文で可能ですが、本件の場合はまったく、方法が分かりません。

環境:PostgreSQL 10

ご教授頂きたく。よろしくお願いします。

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

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

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

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

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

yambejp

2021/06/18 06:15 編集

Postgreのタグをつけた方がよいですよ ptimeはユニークが保証されているのでしょうか?
hideki.

2021/06/18 06:27

アドバイスありがとうございます。 タグ付けしてptimeカラムがユニークであることを追記しました。
guest

回答2

0

ベストアンサー

普通にかくと

SQL

1select (select max(ptime) from tbl 2where ptime<t1.ptime) as start_time, 3ptime as end_time,col_a,col_b 4 from tbl as t1; 5

しぼりこんでこう?

SQL

1select (select max(ptime) from tbl 2where ptime<t1.ptime) as start_time, 3ptime as end_time 4 from tbl as t1 5where (col_a,col_b) in (select -1,1)

投稿2021/06/18 06:25

yambejp

総合スコア114829

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

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

hideki.

2021/06/18 07:22

超高速の回答ありがとうございます。 ご提示頂いたSQLで、欲しい結果が得られました。 但し、内容は理解できていません。 上のコードはstart_tmとend_tmのテーブル作成、下のコードはそこからcol_a=-1、col_b=1のレコードを抽出ですね。 上のコードのmax()、as t1や下のコードのin(select )のあたりの使い方がキーポイントと推測しますが、参考となるサイト紹介か、解説を頂けると幸いです(うまい検索ワードが浮かびません)。 よろしくお願いします。
yambejp

2021/06/18 07:29

基本は select * from tbl as t1 where col_a=-1 and col_b=1 inは見た目を変えただけでやってることは同じです a=1 and b=2 and c=3→(a,b,c) in (select 1,2,3) みたいな感じ select * from tbl as t1 に対して t1のptimeより小さくて、最大のptimeが1個前のデータですから maxをつかってstart_timeを抽出しています
hideki.

2021/06/18 08:03

解説ありがとうございます。 in (select 1,2,3) は簡潔に書けて便利ですね。 2番目のやり方も勉強になりました。
guest

0

やりかたはいろいろありそうですが、個人的にはウィンドウ関数のLAGを使うとシンプルになるかと思います。

SQL

1SELECT start_tm, end_tm 2FROM ( 3 SELECT LAG(ptime) OVER (ORDER BY ptime) AS start_tm, ptime AS end_tm, col_a, col_b 4 FROM T 5) U 6WHERE col_a = -1 AND col_b = 1

投稿2021/06/18 07:36

neko_the_shadow

総合スコア2230

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

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

hideki.

2021/06/18 08:31

回答ありがとうございます。 neko_the_shaadow様のSQLでも欲しい結果が得られました。 window関数を使って何とかできないか、考えましたが、自分の力ではできずにあきらめていました。参考にさせて頂きます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問