2 つのテーブルがあるとします。
注文
order_id , ....
1, ...
2, ...
各注文には「状態履歴」があります。これは履歴テーブルに保存されます。
serial, date, order_id , order_state
10, 2012-01-01, 1, 'INIT'
11, 2012-01-02, 2, 'INIT'
12, 2012-02-03, 1, 'COMPLETED'
13, 2012-02-04, 1, 'DISPATCHED'
14, 2012-02-05, 2, 'COMPLETED'
15, 2012-02-06, 2, 'DISPATCHED'
ここで、過去の任意の時点でのすべての注文の状態を知りたいと考えています。たとえば、2012 年 2 月 5 日の注文の状態を知りたいとします。
order_id, order_state, state_date
1 , 'DISPATCHED' , 2012-02-04
2, 'COMPLETED' , 2012-02-05
(state_date 列はオプションです)。
アプリケーションコードで注文をループして「特定の日付の状態」を取得するよりも効率的にそれを行う1つのクエリを作成する方法はありますか?
私はPostgresqlのrank() WINDOW関数でそれをうまくやったが、ランク1のものを選ぶためだけに(指定された日付の前に)すべての履歴を取得しなければならないという事実にあまり満足していない.私の見解ではアプリのコードで実行するよりも優れているわけではありません。
SELECT * FROM ( SELECT o.order_id,
h.order_state,
h.state_date,
rank() ON (PARTITION BY order_id ORDER BY h.serial DESC)
AS hrank
FROM order o, history h
WHERE
h.order_id = o.order_id AND
h.date < given_date
) AS rh
WHERE
rh.hrank = 1;
私が本当に欲しいのは、私のパーティション定義にある種の LIMIT 1 ですが、それが可能かどうかはわかりません。