這是非常簡單相乘作爲窗口函數的集合。
您沒有指定您的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
值。
select id,
postdate,
return,
row_number() over (order by postdate) as rn,
first_value(return) over (order by postdate) as base_value
from adi
有了這個結果,我們可以創建最終的查詢:
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;
這將返回以下結果:
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
查詢這可以使用窗口函數來完成除了自定義聚合函數之外,它幾乎是標準的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