4

製品 (*) の集計を PostgreSQL で作成しようとしています。私の行のフィールドタイプは「倍精度」です

だから、私は試しました:

CREATE AGGREGATE nmul(numeric)
(
   sfunc = numeric_mul,
   stype = numeric
);

クエリを起動すると、結果:

ERROR:  function nmul(double precision) does not exist
LINE 4: CAST(nmul("cote") AS INT),

ありがとうございました

4

2 に答える 2

8

double precision入力を( float8) からにキャストするか、集計numericのフレーバーを定義します。double precision

あなたの集計はうまくいきます:

regress=> CREATE AGGREGATE nmul(numeric)
regress-> (
regress(>    sfunc = numeric_mul,
regress(>    stype = numeric
regress(> );

regress=> SELECT nmul(x) FROM generate_series(1,100) x;
                                                                              nmul                                                                              
----------------------------------------------------------------------------------------------------------------------------------------------------------------
 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
(1 row)

問題はあなたのクエリです:

regress=> SELECT nmul(x::float8) FROM generate_series(1,100) x;                                                                                                                
ERROR:  function nmul(double precision) does not exist                                                                                                                         
LINE 1: SELECT nmul(x::float8) FROM generate_series(1,100) x;                                                                                                                  
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

float8集計のバージョンを定義できます(float8は の同義語ですdouble precision)。

regress=> CREATE AGGREGATE nmul(double precision)
(
   sfunc = float8mul,
   stype = float8
);

regress=> SELECT nmul(x::float8) FROM generate_series(1,100) x;
         fmul          
-----------------------
 9.33262154439441e+157
(1 row)

numericまたは、値の完全な精度を保持したい場合は、集計の前にキャストします。たとえば、次のようになります。

CAST(nmul(CAST("cote" AS numeric)) AS INT)

または PostgreSQL 固有の短縮キャスト:

nmul("cote"::numeric)::integer

integerこれらの製品集計を使用している場合、すぐにオーバーフローすることに注意してください。

regress=> SELECT nmul(x)::integer FROM generate_series(1,12) x;
   nmul    
-----------
 479001600
(1 row)

regress=> SELECT nmul(x)::integer FROM generate_series(1,13) x;
ERROR:  integer out of range
regress=> 

numericとにかく使い続けたいと思うでしょう。

于 2012-10-31T10:48:42.950 に答える