SQL Dojo Beta
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_noroundedfee_share
10.330.34
20.330.33
30.330.33
Provalo in Randori