Técnica
Reparto con resto
Repartir un importe entre filas según un peso, redondeado al céntimo, con el resto en una fila elegida para que las partes sumen exactamente el total.
Parte = ROUND(amount × weight / SUM(weight) OVER (PARTITION BY parent), 2). Redondear cada parte pierde o añade un
céntimo: asigne amount − SUM(share) OVER (PARTITION BY parent) a una sola fila elegida con una regla fija (la mayor, y luego el
id más pequeño). Compruébelo: por cada padre, las partes suman el importe. Se usa para comisiones, gastos de envío, descuentos de pedido, presupuestos.
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 |
Practicar:Spread the fee over the lines