如何在记录之间分配值

时间:2011-05-05 12:30:45

标签: algorithm tsql sql-server-2008

我的值为1000,表格为:

table
(
  Id int (PK),
  Percent float,
  Value int
)

我必须根据两个法律(两个分离策略)为此表中的每个记录分配1000字段值:

1)平等分配策略

2)分配策略的百分比

按策略输入1)

Id  Percent Value
1,  -       0
2,  -       0
3,  -       0

输出

Id  Percent Value
1,  -       333
2,  -       333
3,  -       334

按策略输入2)

 Id  Percent Value
 1,  10%       0
 2,  90%       0

输出

Id  Percent Value
1,  10%       100
2,  90%       900

任何人都可以解释一种优雅的方式来做到这一点。 谢谢。

2 个答案:

答案 0 :(得分:1)

UPDATE yourtable SET Value =( SELECT 1000/COUNT(Value) from yourtable )

UPDATE yourtable SET Value =( Value * Percent )

不知道如何处理舍入错误。

编辑:可能在第一种情况下使用第二个语句将缺失的数字添加到最后一行。

UPDATE yourtable SET Value = Value + 1000 -( SELECT SUM(Value) from yourtable) where id= (SELECT MAX(Id) from yourtable)

但这并不好,因为最后一行可能会以更大的数字结束......你最终会得到比其他数字大得多的数字。 (尝试使用6个输入行运行查询...)

答案 1 :(得分:0)

DECLARE @valueToDistribute float;
SET @valueToDistribute = 100;

DECLARE @rest int;
DECLARE @temp int;
SET @temp = 0;
DECLARE @error float
SET @error = 0;

DECLARE @tableToDistribute table
(
    id                  int
    ,MaxValue           int 
    ,InitialValue       int 
    ,DistributedValue   int
);

INSERT @tableToDistribute values(1, 0, 0, 0);
INSERT @tableToDistribute values(2, 0, 0, 0);

INSERT @tableToDistribute values(3, 0, 0, 0);
INSERT @tableToDistribute values(4, 0, 0, 0);
INSERT @tableToDistribute values(5, 0, 0, 0);
INSERT @tableToDistribute values(6, 0, 0, 0);
--INSERT @tableToDistribute values(7, 0, 0, 0);
--INSERT @tableToDistribute values(8, 0, 0, 0);
--INSERT @tableToDistribute values(9, 0, 0, 0);


SET   @rest = @valueToDistribute;

WITH Count_CTE (Id, [Percent], MaxId)
AS
(
   SELECT 
          Id
        , [Percent] = CAST(@valueToDistribute / (SELECT COUNT(*) FROM @tableToDistribute) / 100.00 as float)
        , [MaxId] = (SELECT MAX(Id) FROM @tableToDistribute)
    FROM @tableToDistribute
)
UPDATE t 
    SET
       @error = @error + (cte.[Percent] * @valueToDistribute) - ROUND(cte.[Percent] * @valueToDistribute, 0)
      ,@temp = 
        case
            when ROUND(@error, 5) <> 0.00000
                then 
                    case 
                        when t.Id = cte.MaxId then @rest --ROUND(cte.[Percent] * @valueToDistribute, 0) + FLOOR(@error)
                        else ROUND(cte.[Percent] * @valueToDistribute, 0)
                    end 
            else  ROUND(cte.[Percent] * @valueToDistribute, 0)      
        end 
      ,DistributedValue = @temp
      ,@rest = @rest - @temp
FROM @tableToDistribute t 
    inner join Count_CTE cte on t.Id = cte.Id;


SELECT
*
FROM @tableToDistribute