[pgsql-jp: 36898] Re: 項目毎に件数指定をしたい

Yasuhiro Shibutani yasuhiro_shibutani @ ybb.ne.jp
2006年 3月 19日 (日) 18:34:35 JST


初めまして、渋谷といいます。

パフォーマンスを気にされるなら plpgsql でループを使った方が
いいのではないかと思います。

CREATE OR REPLACE FUNCTION "rank_table1_f1" (
  "_top_n" integer
)
RETURNS SETOF "table1" AS
$body$
DECLARE
  "_id" record;
  "_ret" "table1"%ROWTYPE;
BEGIN

  FOR "_id" IN
    SELECT "ID" FROM "table1"
    GROUP BY "ID" ORDER BY "ID"
  LOOP

    FOR "_ret" IN
      SELECT * FROM "table1"
      WHERE "ID" = "_id"."ID"
      ORDER BY "f1" DESC LIMIT "_top_n"
    LOOP
      RETURN NEXT "_ret";
    END LOOP;

  END LOOP;

  RETURN;

END;
$body$
LANGUAGE 'plpgsql'
STABLE CALLED ON NULL INPUT
SECURITY INVOKER;


SELECT * FROM rank_table1_f1(2);


ID のマスタテーブルがあるなら外側のループのクエリは書き換え、
同順 N 位を出力する必要があるなら内側のクエリを書き換えで。

インデックス ID, f1 があれば 50万件でも数秒じゃないかと。
(試してはないですが・・・)


-- 
渋谷 泰宏


On Sat, 18 Mar 2006 14:38:05 +0900
西村 篤史 <a2c @ lets-heart.co.jp> wrote:

> 西村@和歌山市です。
> 
> >> つまり、左端のカラム「ID」ごとにカラム「f1」の値が大きい順に
> >> 上位2位までを表示したいのですが、Select文ではどう書けば良いので
> >> しょうか?
> 
> odagiri atsushi wrote:
> > select *
> > from ex1 e
> > where seq in (select seq from ex1 f where f.id = e.id order by
> > f1 limit 2)
> > order by e.id , e.f1 desc
> 
> 相関クエリというのを知りました。
> レコード数を増やしてやってみましたら、欲しい形の表を得られる事が
> できました。
> 
> >相関クエリなので、パフォーマンスは保障できませんが
> 50万レコードある本番用(といってもまだテスト)のテーブルを使い、
> ビューを作ってから相関クエリを実行させたんですが、マシンスペックの
> 低さも相まって、2時間経っても答えが返ってきませんでした(w
> 
> 「各部門毎に売上金額の上位 n位の商品を降順で出力」といった処理に
> つかうには、スペックアップや夜間バッチ等で作っておく表などの
> チューニングも必要みたいですね。
> 
> from table1 t1 ( from table1 as t1)という文法も知りました。
> 
> rish さん、小田切さん、中司さん、ありがとうございました。

-- 
Yasuhiro Shibutani <shibutani-yxa @ necst.nec.co.jp>




pgsql-jp メーリングリストの案内