ここで何らかのタイプの「割り当て」をしているようです。これは、高精度のグラニュラリティからより低いグラニュラリティに何かを割り当てようとするときはいつでも共通の問題であり、合計値に正しく再集計できる必要があります。
より大きな分数を扱う場合、これははるかに大きな問題になります。
たとえば、$ 55.30という合計値を8で割ると、8つのバケットのそれぞれに対して$ 6.9125の小数値が得られます。 1つを$ 6.92に、残りを$ 6.91に丸めてください。もしそうすれば、私は1セントを失うだろう。 1つを$ 6.93に、他のものを$ 6.91に丸める必要があります。あなたが分割するバケツを追加すると、これは悪化します。
さらに、ラウンドを開始するときに、「33.339を33.34または33.33に丸める必要がありますか」などの問題が導入されます。
あなたのビジネスロジックが、2桁の有効数字を超えて残りのものを取っておき、それをドル値の1つに「無作為に」追加してセントを失うことがないようなものなら、@Diegoはこれで正しい軌道に乗っています。
純粋なSQLで行うのは少し難しいです。初心者の場合、パーセンテージは1/3ではなく、0.33で、合計値は9.9で、10ではなくなります。これを比率または高精度小数点フィールド(.33333333333333)として保存します。
P S PCT Total
-- -- ------------ ------
P1 S1 .33333333333 10.00
P2 S2 .33333333333 10.00
P3 S3 .33333333333 10.00
SELECT
BaseTable.P, BaseTable.S,
CASE WHEN BaseTable.S = TotalTable.MinS
THEN BaseTable.BaseAllocatedValue + TotalTable.Remainder
ELSE BaseTable.BaseAllocatedValue
END As AllocatedValue
FROM
(SELECT
P, S, FLOOR((PCT * Total * 100))/100 as BaseAllocatedValue,
FROM dataTable) BaseTable
INNER JOIN
(SELECT
P, MIN(S) AS MinS,
SUM((PCT * Total) - FLOOR((PCT * Total * 100))/100) as Remainder,
FROM dataTable
GROUP BY P) as TotalTable
ON (BaseTable.P = TotalTable.P)
あなたの計算は、サプライヤあたりの総製品数に基づいて均等な分配であるようです。そうであれば、パーセンテージを削除し、代わりにサプライヤごとのアイテムの数をテーブルに格納することが有利な場合があります。
剰余値を取得する行を示すフラグを格納することも可能な場合は、ランダムにではなく、そのフラグに基づいて割り当てることができます。