これは、窓関数としての乗算集計を使用して非常に簡単です。
DBMSを指定していないため、以下はPostgreSQLです。
テストテーブルを作成します。
create table adi (id integer, postdate date, return integer);
insert into adi (id, postdate, return)
values
(1001, date '2013-07-01', 100),
(1001, date '2013-07-02', 101),
(1001, date '2013-07-03', 102),
(1001, date '2013-07-04', 103);
すべての値を乗算集合体を作成する:
create aggregate mult(bigint)
(
sfunc = int8mul,
stype=bigint
);
我々は数字の行とは最初の行のreturn
値を保持することの結果を必要とします。
id | postdate | return | linkedvalue
-----+------------+--------+------------
1001 | 2013-07-01 | 100 | 100
1001 | 2013-07-02 | 101 | 101.00
1001 | 2013-07-03 | 102 | 103.02
1001 | 2013-07-04 | 103 | 10611.06
クエリ:
with numbered as (
select id,
postdate,
return,
row_number() over (order by postdate) as rn,
first_value(return) over (order by postdate) as base_value
from adi
)
-- only get the first row, so that the return value of that
-- is not included in the running aggregate
select id,
postdate,
return,
return as linkedvalue
from numbered
where rn = 1
union all
select id,
postdate,
return,
(mult(return) over (order by postdate))::numeric/(case when rn > 2 then base_value else 1 end)
from numbered
where rn > 1;
これは、次の結果を返します。私たちは、最終的なクエリを作成することができ、この結果で
select id,
postdate,
return,
row_number() over (order by postdate) as rn,
first_value(return) over (order by postdate) as base_value
from adi
:これは、ウィンドウ関数を使用して行うことができますカスタム集計関数を除いて、ほとんど標準のANSI SQLです。使用しているDBMSの定義方法は、そのDBMSによって異なります。
カスタム集計を作成できない場合、これは再帰的なCTEを使用して行うことができます。以下は、製品固有の構文を使用しない標準ANSI SQLです。
with recursive numbered as (
select id,
postdate,
return,
row_number() over (order by postdate) as rn,
first_value(return) over (order by postdate) as base_value
from adi
), calc as (
select id, postdate, return, return as linkedvalue, base_value, rn
from numbered
where rn = 1
union all
select c.id, c.postdate, c.return,
case when c.rn > 2 then (c.return * p.linkedvalue) else c.return end,
p.base_value,
c.rn
from numbered c
join calc p on c.rn - 1 = p.rn
where c.rn > 1
)
select id, postdate, return,
case when
rn > 2 then cast(linkedvalue as numeric)/100
else linkedvalue
end as linkedvalue
from calc
order by postdate;
どのようなrdbmsを使用していますか? –
ウィンドウ関数としてカスタム集計を使用するのは簡単です。どのように行の順序を定義しますか?リレーショナルデータベースでは、「注文する」ものがない限り、「最初の行」というものはありません。あなたの例の行の順序は 'postdate'列によって定義されていますか?または別の列ですか? –
この例は明確ではありません。 LinkedValuesは100,10100,1030200,106110600のいずれかですか? – knagaev