[pgsql-jp: 39014] 行番号を取得するユーザー関数について

dai_sha_ring @ yahoo.co.jp dai_sha_ring @ yahoo.co.jp
2007年 12月 21日 (金) 20:50:19 JST


PostgreSQL8.2にてOracleのRownumのような、行番号を取得す
る
ユーザー関数を作りたいと思っています。
以下のような関数をつくり、行番号を取得しようと考えている
のですが
どうしても思ったような動作ができず投稿させていただきまし
た。

-- function:[getrownum(text)]
CREATE OR REPLACE FUNCTION getRownum(text) RETURNS INTEGER
AS
'
DECLARE
         seq_tmpname ALIAS FOR ;
         seq_count INTEGER DEFAULT 0;
         ret_value INTEGER DEFAULT 0; 
         sql TEXT; 
BEGIN
         SELECT COUNT(*) INTO seq_count FROM pg_class
WHERE relname=seq_tmpname ;
        IF seq_count=0 THEN
                  sql := ''CREATE TEMP SEQUENCE
''||seq_tmpname;
                  EXECUTE sql;
         END IF;
         SELECT NEXTVAL(seq_tmpname) INTO ret_value;
         RETURN ret_value;
END; 
' 
LANGUAGE 'plpgsql';


たとえば、下のような日付順にソートされたテーブル(ビュー)
があり、
[view_datatable]
-----------------------------------
p_date(timestamp)  p_value(integer)
-----------------------------------
2007/12/01         10
2007/12/02         15
2007/12/04         30
2007/12/07         45
2007/12/08         50
2007/12/09         75

このテーブルから1つ前のレコードからの増加量を求めようと
しています。
そこで、作成した関数を使用して下のようなビューを作成しま
した。

[view_datatable_offset]
CREATE VIEW view_datatable_offset AS
         SELECT
          tbl1.p_date
         ,tbl2.p_value AS p_value_tbl2
         ,tbl1.p_value AS p_value_tbl1
         ,tbl1.p_value-tbl2.p_value AS p_value_offset
          FROM
         (SELECT
          getrownum('tmpseq1') AS rownum,*
          FROM view_datatable ORDER BY p_date
         ) AS tbl1
         ,
         (SELECT
          getrownum('tmpseq2')+1 AS rownum,*
          FROM view_datatable ORDER BY p_date
         ) AS tbl2
         
         WHERE tbl1.rownum = tbl2.rownum;

これで、

SELECT * FROM view_datatable_offset 

というSQLを発行しますと
--------------------------------------------------
p_date      p_value_tbl2 p_value_tbl1 p_value_offset
--------------------------------------------------
2007/12/02  10           15           5
2007/12/04  15           30           15
2007/12/07  30           45           15
2007/12/08  45           50           5
2007/12/09  50           75           25

と、予想どおりの結果が帰ってくるのですが、

SELECT * FROM view_datatable_offset WHERE p_value_tbl1 =
15

という風に条件をいれると結果がもどってきません。
また、

SELECT * FROM view_datatable_offset WHERE p_date >
'2007/12/07'

という条件をいれると、
--------------------------------------------------
p_date      p_value_tbl2 p_value_tbl1 p_value_offset
--------------------------------------------------
2007/12/08  45           50           5
2007/12/09  50           75           25
という結果が帰らず、

--------------------------------------------------
p_date      p_value_tbl2 p_value_tbl1 p_value_offset
--------------------------------------------------
2007/12/09  10           75           65
という結果になってしまいます。


この問題について、他の掲示板にて質問をし、行番号を使用し
ない
代替え案をアドバイスいただいたのですが、速度的に不安な面
があ
り、どうにかして、ユーザー関数で行番号を取得できないか悩
んで
います。

長文で申し訳ありませんが、ご教授よろしくお願いします。




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