Как распределить значения между записями - PullRequest
0 голосов
/ 05 мая 2011

У меня есть значение 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 ]

1 голос
/ 05 мая 2011
UPDATE yourtable SET Value =( SELECT 1000/COUNT(Value) from yourtable )

UPDATE yourtable SET Value =( Value * Percent )

Не знаю, как обрабатывать ошибки округления.

edit: возможно, в первом случае со вторым оператором, который добавляет пропущенные числа в последнюю строку.

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

Но это нехорошо, так как последний ряд может закончиться гораздо большим числом ... у вас получится значительно большее число, чем остальные.(попробуйте выполнить запрос с 6 входными строками ...)

0 голосов
/ 05 мая 2011
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...