それは些細なことかもしれません..
select log_number,
...
rank() over (
partition by code_id, buyer_id
order by (date_trunc('second',cdr.dateconso)
- date_trunc('second',log.datecrea))
) as ranking,
from ...
..実際に最後の項目の後にコンマがある場合(これはすべきではありません)。SELECT
.. か否か
後のコメントで明らかにされているように、目的は、ウィンドウ関数のない古いバージョンの PostgreSQL (バージョン 8.2 以前) でエミュレートすることです。rank()
本当にすべきことは、ウィンドウ機能を備えたより新しいバージョン (PostgreSQL 8.4 以降) にアップグレードすることです。PostgreSQL 8.2 は 2011 年 12 月にサポートが終了しました。
それを除けば、 PostgreSQL 8.2の一時シーケンス、一時テーブル、いくつかのサブクエリ、および集計関数rank()
を使用してエミュレートできます。しかし、それはきれいではありません:
テストのセットアップ(あなたの例から簡略化)
CREATE TEMP TABLE t(code_id int, buyer_id int, the_date date);
INSERT INTO t VALUES
(1, 1, '2012-08-01')
,(1, 1, '2012-08-01')
,(1, 1, '2012-08-01')
,(1, 1, '2012-08-02')
,(1, 1, '2012-08-03')
,(1, 1, '2012-08-04')
,(2, 3, '2012-09-01')
,(2, 3, '2012-09-02')
,(2, 3, '2012-09-02')
,(2, 3, '2012-09-02')
,(2, 3, '2012-09-04')
,(2, 3, '2012-09-06');
一時テーブルを使用して、結果を複数回再利用します。現代の PostgreSQL では、代わりに CTE を使用します。一時的なシーケンスは
、. すべての列で基本的な行番号の順序を取得するには-その順序で:row_number()
nextval()
PARTITION BY
ORDER BY
rank()
CREATE TEMP SEQUENCE t_seq; -- once per session ..
-- SELECT setval('t_seq', 1, FALSE); -- .. or reset for repeated use
-- DROP TABLE tmp;
CREATE TEMP TABLE tmp AS -- once per session or drop first
SELECT code_id
,buyer_id
,the_date
,nextval('t_seq') AS rownum
-- rank() included to compare results in modern version
-- remove this line in old version:
,rank() OVER (PARTITION BY code_id, buyer_id ORDER BY the_date) AS rnk
FROM t
ORDER BY code_id, buyer_id, the_date;
Depesz がここで示しているような言語C
関数を書くこともできます...
rownum
次に、ピア グループごとの最小値を取得し( subquery peer
)、グループごとの最小値を減算してrownum
( subquery grp
)、実際の行番号に到達します。
SELECT t.*, peer.rn - grp.rn AS rnk_8_2
FROM tmp t
JOIN (
SELECT code_id, buyer_id, min(rownum) -1 AS rn
FROM tmp
GROUP BY code_id, buyer_id
) grp USING (code_id, buyer_id)
JOIN (
SELECT code_id, buyer_id, the_date, min(rownum) AS rn
FROM tmp
GROUP BY code_id, buyer_id, the_date
) peer USING (code_id, buyer_id, the_date)
ORDER BY code_id, buyer_id, the_date;
出来上がり。rnk_8_2
一致しrnk
ます。
クリーンアップ (またはセッションの終了時にオブジェクトを削除):
DROP SEQUENCE t_seq;
DROP TABLE t, tmp;
セッション/実行ごとに一時オブジェクトを作成/リセット/再作成する必要があることに注意してください。
PostgreSQL 9.1 でテスト済みですが、8.2 でも動作するはずです。