Tecnica
Ripartizione con resto
Ripartisci un importo sulle righe in base a un peso, arrotondato al centesimo, con il resto su una riga scelta, così che le parti diano esattamente il totale.
Quota = ROUND(amount × weight / SUM(weight) OVER (PARTITION BY parent), 2). Arrotondare ogni quota fa perdere o
aggiungere un centesimo: assegna amount − SUM(share) OVER (PARTITION BY parent) a una riga scelta con una regola fissa
(la più grande, poi l'id più piccolo). Verificalo: per ogni parent, le quote sommano all'importo. Si usa per commissioni,
spese di spedizione, sconti sull'ordine, budget.
WITH lines(line_no, amount) AS (VALUES (1, 10.00), (2, 10.00), (3, 10.00)),
shares AS (
SELECT line_no, amount,
CAST(ROUND(1.00 * amount / SUM(amount) OVER (), 2) AS DECIMAL(10,2)) AS rounded,
ROW_NUMBER() OVER (ORDER BY amount DESC, line_no) AS rank_in_order
FROM lines
)
SELECT line_no, rounded,
rounded + CASE WHEN rank_in_order = 1 THEN 1.00 - SUM(rounded) OVER () ELSE 0 END AS fee_share
FROM shares
ORDER BY line_no;
| line_no | rounded | fee_share |
|---|---|---|
| 1 | 0.33 | 0.34 |
| 2 | 0.33 | 0.33 |
| 3 | 0.33 | 0.33 |
Esercitati:Spread the fee over the lines