Prova:
DECLARE @t TABLE
(
ID INT ,
wac DECIMAL(30, 10) ,
item CHAR(1)
)
DECLARE @b TABLE
(
item CHAR(1) ,
baseline DECIMAL(30, 10)
)
INSERT INTO @t
VALUES (1, 2.31, 'A'),
(2, 1.10, 'A'),
(3, 2.13, 'A'),
(4, 1.34, 'A')
INSERT INTO @b
VALUES ('A', 10);
WITH ordercte
AS (SELECT * ,
ROW_NUMBER() OVER (PARTITION BY item ORDER BY ID) AS rn
FROM @t
),
rec
AS (SELECT t.item ,
t.ID ,
t.wac ,
t.rn ,
b.baseline * (1 + (t.wac/100)) AS m
FROM ordercte t
JOIN @b b ON b.item = t.item
WHERE t.rn = 1
UNION ALL
SELECT t.item ,
t.ID ,
t.wac ,
t.rn ,
c.m * (1 + (t.wac/100))
FROM ordercte t
JOIN rec c ON t.item = c.item
AND t.rn = c.rn + 1
)
SELECT id ,
wac ,
item ,
m
FROM rec
uscita:
id wac item m
1 2.3100000000 A 10.231000
2 1.1000000000 A 10.343541
3 2.1300000000 A 10.563858
4 1.3400000000 A 10.705414
EDIT1
stavo cercando di implementare LOG EXP trucco, ma non riuscivo a meno @usr mi portano a soluzione. Quindi tutti i crediti a @usr utente:
WITH ordercte
AS (SELECT t.ID ,
t.wac ,
t.item ,
b.baseline ,
ROW_NUMBER() OVER (PARTITION BY t.item ORDER BY ID) AS rn
FROM @t t
JOIN @b b ON b.item = t.item
)
SELECT baseline
* EXP(SUM(LOG((1 + (wac/100)))) OVER (PARTITION BY item ORDER BY rn)) AS m
FROM ordercte
O solo:
SELECT t.ID, t.wac, t.item, baseline
* EXP(SUM(LOG((1 + (wac/100)))) OVER (PARTITION BY t.item ORDER BY t.ID)) AS m
FROM @t t
JOIN @b b ON b.item = t.item
se ID è il campo si ordina per.
uscita:
ID wac item m
1 2.3100000000 A 10.231
2 1.1000000000 A 10.343541
3 2.1300000000 A 10.5638584233
4 1.3400000000 A 10.7054141261722
EDIT2
Per SQL 2008 Usa:
WITH cte
AS (SELECT t.ID ,
t.wac ,
t.item ,
baseline ,
(SELECT SUM(LOG((1 + (wac/100))))
FROM @t it
WHERE it.item = t.item AND it.ID <= t.ID
) AS e
FROM @t t
JOIN @b b ON b.item = t.item
)
SELECT ID, wac, item, baseline * EXP(e) AS m
FROM cte
Edit3
Ecco soluzione completa per SQL Servire r 2008 con la composizione con i NULL e valori negativi:
WITH cte
AS (SELECT t.ID ,
t.wac ,
t.item ,
b.baseline ,
ca.e,
ca.n,
ca.m
FROM @t t
JOIN @b b ON b.item = t.item
CROSS APPLY(SELECT SUM(LOG(ABS(NULLIF(1 + wac/100 , 0)))) as e,
SUM(SIGN(CASE WHEN 1 + wac/100 < 0 THEN 1 ELSE 0 END)) AS n,
MIN(ABS(1 + wac/100)) AS m
FROM @t it
WHERE it.item = t.item AND it.ID <= t.ID
) ca
)
SELECT ID, wac, item, baseline *
CASE
WHEN m = 0 THEN 0
WHEN n % 2 = 1 THEN -1 * EXP(e)
ELSE EXP(e)
END as Result
FROM cte
È possibile eseguire il logaritmo e calcolare una somma parziale poiché exp (log (a) + log (b)) = a * b'. Non sono sicuro della precisione numerica che conserva. – usr
@usr - puoi condividere un esempio –
Penso che sarebbe 'exp (sum (log (x)))'. – usr