web-dev-qa-db-ja.com

PostgreSQLの行番号付け

結果がいくつかの列で順序付けられているときにPostgreSQLで行番号を取得する方法は?

例えば.

SELECT 30+row_number() AS position, * 
FROM users 
ORDER BY salary DESC 
LIMIT 30 
OFFSET 30

クエリが次のようなリストを返すと想定しました。

position | name | salary
31       | Joy  | 4500
32       | Katie| 4000
33       | Frank| 3500

実際には、ORDER句をクエリに複製して機能させる必要があります。

SELECT 30+row_number(ORDER BY salary DESC) AS position, * 
FROM users 
ORDER BY salary DESC 
LIMIT 30 
OFFSET 30

コードを複製する必要なく、順序付けられた番号付きの結果を返す方法は他にありますか?

これはアプリ自体の変数を増やすことで解決できることはわかっていますが、データベース層でこれを行い、既に番号付けされた結果にアプリに戻りたい...

27
Radek Simko

no-ウィンドウ関数のorder byselectステートメントのorder by句は、機能的に2つの異なるものです。

また、ステートメントはERROR: window function call requires an OVER clauseを生成します。

SELECT 30+row_number(ORDER BY salary DESC) AS position, * FROM users ORDER BY salary DESC LIMIT 30 OFFSET 30

する必要があります:

SELECT 30+row_number() OVER(ORDER BY salary DESC) AS position, * FROM users ORDER BY salary DESC LIMIT 30 OFFSET 30

給与が一意でない場合、同じ順序を生成する保証さえないことに注意してください。おそらくそれを行う方が良いでしょう:

SELECT * 
FROM ( SELECT 30+row_number() OVER(ORDER BY salary DESC) AS position, * 
       FROM users )
ORDER BY position LIMIT 30 OFFSET 30

また、異なるオフセットでこのクエリを複数回実行する場合は、次のことを行う必要があることに注意してください。

  1. 分離レベル をシリアライズ可能に設定します
  2. 注文するものはすべて一意であることを確認してください

または、重複して行が欠落する場合があります。理由については、 this answer のコメントを参照してください。

37
user533832