あなたはここで何らかのタイプの「割り当て」をしているようですね。これは、高精度のグラニュラリティからより低いグラニュラリティに何かを割り当てようとするときはいつでも共通の問題であり、合計値に正しく再集計できる必要があります。
これは、より大きな分数を処理する場合にはるかに大きな問題になります。
例えば、$ 55.30という合計値を8で除算しようとすると、8つのバケットごとに10進数の値が$ 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)
あなたの計算は、サプライヤあたりの製品の総数に基づいて均等に分布しているようです。そうであれば、パーセンテージを削除し、代わりにサプライヤごとのアイテムの数をテーブルに格納することが有利な場合があります。
剰余値を適用する行を示すフラグを格納することもできますが、ランダムにではなくそのフラグに基づいて割り当てることができます。
の一部であるあなたは、なぜ 'percentage'列に' 0.33333333333333'に入れていない、割合は14小数点以下の桁数を持っていますか? – beny23
私が言いたい場合、あなたはそれはあなたが実際にちょうどこの質問を読んで必要なものを理解することがいかに難しい理解かもしれない... –
は、Martin Fowler氏のを見て、「あなただけのSETサプライヤーを更新することができます... 0.34 =割合」 「数量」パターン。 http://martinfowler.com/eaaDev/quantity.html特に、資金の分割に関する議論を見てください。この例の除算は、単一の値ではなく、値の配列を返します。値の配列は合計に加算されます。私は、それが得られるほど簡単だとわかった。 – Glenn