SQL Dojo Bêta
Technique

Répartition avec reste

Répartir un montant sur des lignes selon un poids, arrondi au centime, avec le reste sur une ligne choisie pour que les parts fassent exactement le total.

Part = ROUND(montant × poids / SUM(poids) OVER (PARTITION BY parent), 2). Arrondir chaque part perd ou ajoute un centime : donnez montant − SUM(part) OVER (PARTITION BY parent) à une ligne choisie par une règle fixe (la plus grosse, puis le plus petit identifiant). Testez-la : par parent, les parts font le montant. Sert aux frais, aux frais de port, aux remises de commande, aux budgets.

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
L’essayer en Randori