0

herokuにデプロイするWebアプリを作成しました。PostgreSQL9.1.2を使用して作成しました。しかし、herokuの無料の共有データベースはpostgres8.3にすぎないようです。それらは9にアップグレードしています。近いうちに何かが発生しますが、それまでは、私のSQLクエリの1つが機能しません。それは:

SELECT id, route_id, location_id, order_id, blogtext,
  lead(id) over (PARTITION BY route_id ORDER BY order_id ASC) AS next_id,
  lead(location_id) over (PARTITION BY route_id ORDER BY order_id ASC) AS next_location_id,
  lag(id) over (PARTITION BY route_id ORDER BY order_id ASC) as previous_id,
  lag(location_id) over (PARTITION BY route_id ORDER BY order_id ASC) AS previous_location_id,
  row_number() over (PARTITION BY route_id ORDER BY order_id ASC) AS indx

PostgreSQL 8.3で動作するようにこれを書き直すことは可能ですか?

4

1 に答える 1

2

Window関数は8.4より前のPostgreSQLには存在しないことに注意してください。


EDIT2:

あなたは私を本当に好奇心をそそり、私は質問をいじってみました。

最初に注意すべき点:

  1. 目的の結果を得るには、テーブルをそれ自体と何度も結合する必要があります。PostgreSQL 8.3がCTEをサポートしていないため、ビューを作成しました。OVER ()幸いなことに、すべてのウィンドウ関数に同じ条件を使用するため、必要なビューは1つだけです。

  2. row_numberデータサブセットを操作するために使用する必要があるため、このフィールドをビューに追加しました。

  3. を形成するには、句のすべてのフィールドの結合テーブルで演算子をPARTITION使用する必要があります。=PARTITION

  4. row_numberサブクエリ(結合なし)を使用して形成され、パーティションにORDER BY一致し、現在のフィールド以下のフィールドを持つすべての行をカウントします。フィールドが一意でない場合、このアプローチは機能しないことに注意してください。ORDER BY そうでない場合は、そのようなフィールドを作成します。

  5. 非関数のORDER BY句をシミュレートするには、フィールドで結合して、、、または結合された側にし、それぞれ、、、および関数に一致させます。row_numberrow_number+1-1min()max()lead()lag()first_value()last_value()

上記のポイント4を考慮してください!

クエリは次のように変更できます(使用する前に出力を比較してください)。

-- First, create a support view
CREATE VIEW table_v AS
SELECT id, route_id, location_id, order_id, blogtext,
       (SELECT count(*) FROM table
         WHERE route_id = t.route_id AND order_id <= t.order_id) AS row_number
  FROM table t;

-- Now, the query
SELECT t.id, t.route_id, t.location_id, t.order_id, t.blogtext,
       tlead.id AS next_id, tlead.location_id AS next_location_id,
       tlag.id AS previous_id, tlag.location_id AS previous_location_id,
       t.row_number AS indx
  FROM table_v t
  LEFT JOIN table_v tlead
    ON tlead.route_id = t.route_id AND tlead.row_number = t.row_number + 1
  LEFT JOIN table_v tlag
    ON tlag.route_id = t.route_id AND tlag.row_number = t.row_number - 1
  -- 
  -- proceed with the query here
  -- ...

Window関数からの変更されたサンプルデータとより「ローカルな」集計を使用し、 SQLFiddleでどのように機能するかを示すサンドボックスを作成しました。

それでも、すべての開発が9.1.2で行われたことを考えると、この方法を実行する前に、よく考えます。

于 2012-05-16T18:18:04.710 に答える