0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PostgresSQLで指定した行のレコードを取得したい

Posted at

検索条件の結果行から任意の行のレコードのみを取得する方法を2つ紹介します。
次のようなテーブルを用意して実行結果と合わせて解説していきます。

準備①テーブルを作成

CREATE TABLE sample_tbl
(
  objectid bigserial NOT NULL,
  col1 character varying,
  col2 bigint,
  createdate timestamp without time zone,
  CONSTRAINT sample_tbl_pkey PRIMARY KEY (objectid)
)

準備②サンプルレコードを用意

image.png

【実現方法その1】ROW_NUMBER関数を使う

行番号を付けたうえで、任意の行番号で取得したいレコードを指定する方法です。
まず次のようなSQLで行番号が取得できることが確認できます。
※ROW_NUMBERについて

SELECT ROW_NUMBER() OVER() AS rownum , * FROM sample_tbl;

実行結果
image.png

任意の順番で行番号をつける場合

SELECT ROW_NUMBER() OVER(ORDER BY createdate DESC) AS rownum , * FROM sample_tbl;

実行結果
image.png

それでは、createdateの降順にしたときの2番目のレコードを取得するとしましょう。

SELECT ROW_NUMBER() OVER(ORDER BY createdate DESC) AS rownum , * FROM sample_tbl WHERE rownum = 2;

これで取得できると思いきや、実は次のようなエラーが出ます。
image.png

そのため、サブクエリにする必要があります。

SELECT * FROM 
 (SELECT ROW_NUMBER() OVER(ORDER BY createdate DESC) AS rownum , * FROM sample_tbl) AS tbl
WHERE tbl.rownum = 2;

はい、ちゃんと取得できました。
image.png

【実現方法その2】OFFSETとLIMITを使う

同じようにcreatedateの降順にしたときの2番目のレコードを取得するとしましょう。
次のようなSQLで取得できます。

SELECT * FROM sample_tbl ORDER BY createdate DESC OFFSET 1 LIMIT 1;

取得できていることが確認できます。
image.png

LIMITは取得したいレコードの件数なので特に説明は不要だと思います。
OFFSETは開始したい行という意味ではなく、飛ばす行数を意味しているので、注意してください。
2件目以降が欲しい場合は1件だけ飛ばすので「OFFSET 1」となるのです。
詳しい説明はこちら

まとめ

シンプルな要件に対応するのであれば、OFFSET, LIMITの方が簡単だと思いました。
ただし、○件目~○件目までというような範囲指定はどちらも対応できますが、
○件目と○件目と○件目のような複数の任意行を取得する場合はOFFSET, LIMITではなく、ROW_NUMBERを使った方が柔軟に対応できると思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?