ERPシステムで集計を使用できます(例:SUM(foo)
)が、DISTINCT(例:SUM(DISTINCT foo)
)では使用できません。
SUM(DISTINCT foo)
と同じ結果を返す集約関数(_SUM_DISTINCT
_)を作成して、SUM_DISTINCT(foo) = SUM(DISTINCT foo)
を作成することはできますか?
SUM(DISTINCT foo)
と同じ結果を返す集約関数(_SUM_DISTINCT
_)を作成して、SUM_DISTINCT(foo) = SUM(DISTINCT foo)
を作成することはできますか?
はい、可能です。次のような ユーザー定義の集計 が必要です。
_create or replace function f_sum_distinct (numeric[], numeric) returns numeric[]
language sql as $$
select $1||$2;
$$;
create or replace function f_sum_distinct_final (numeric[]) returns numeric
language sql as $$
select sum(v) from (select distinct unnest($1) v) z;
$$;
create aggregate sum_distinct(numeric)
( sfunc = f_sum_distinct
,stype = numeric[]
,finalfunc = f_sum_distinct_final
);
with w(v) as (select 2 union all select 2 union all select 3)
select sum(v) "Plain SUM", sum(distinct v) "SUM(DISTINCT)", sum_distinct(v) "SUM_DISTINCT" from w;
/*
|Plain SUM|SUM(DISTINCT)|SUM_DISTINCT|
|--------:|------------:|-----------:|
| 7| 5| 5|
*/
_
dbfiddle ここ
ただし(@Erwinに感謝)、パフォーマンスは組み込みの集計よりも 非常に大幅に低下 になることに注意してください。これが問題になる場合は、Cでヘルパー関数を作成することを検討する必要があります。
私は問題を理解しているかどうかわかりません。再ハッシュするだけです...
_>>> 1+2+3+4+5
15
_
データをサンプリングします。
_CREATE TABLE foo
AS
SELECT trunc(random()*5+1) AS x
FROM generate_series(1,100);
_
次に、SUM(DISTINCT..)
_SELECT SUM(DISTINCT x)
FROM foo;
sum
-----
15
_
@JackDouglasが独自のアグリゲートを個別にしたい場合は、アグリゲートを作成します ドキュメントから
SQLの集約関数呼び出しでは、
DISTINCT
および_ORDER BY
_オプションを使用して、集約の遷移関数にどの行をどの順序で送るかを制御できます。 これらのオプションはバックグラウンドで実装されており、アグリゲートのサポート関数の問題ではありません。
これがDISTINCT
とどう関係しているのかわかりません。
独自のsum()
を実装する方法を知りたい場合は、ほぼ正確に(complex
タイプを介して)ドキュメントに記載されています
_CREATE AGGREGATE mysum (numeric)
(
sfunc = numeric_add,
stype = numeric,
initcond = '0'
);
SELECT mysum(x)
FROM ( VALUES (1),(5),(8),(8),(8) )
AS t(x);
SELECT mysum(DISTINCT x)
FROM ( VALUES (1),(5),(8),(8),(8) )
AS t(x);
_
特別な注意として、numeric_add(numeric,numeric)
は 文書化されていない内部関数 です。これは_+
_演算子で使用されますが、2つのnumeric
を必要とする任意のものを配置できます。