Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Распределение суммы с "округлением" до половины  [new]
Читатель неместный
Guest
Возникает время от времени задача распределить сумму (или часы или чего ещё- в примере 9.57)
более или менее "равномерно"
Например так
id	value
1	2.00
2	2.00
3	1.57
4	1.00
5	1.00
6	1.00
7	1.00

Округление до целого кроме одной - с остатком

или так
id	value
1	1.50
2	1.50
3	1.50
4	1.50
5	1.50
6	1.07
7	1.00
округление до "половинки"

Решаю это дело всякий раз по разному (не упомнишь)
Например так
(с учетом что id сформирован через row_number() )
declare @t table ( id int, value numeric(14,2) )
insert into @t (id)
select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7
declare @sum_all numeric(14,2),@cnt int,@h numeric(4,2), @i int
select @sum_all = 9.57
	, @h = 1
	--, @h = .5
	, @cnt= count(*) 
from @t

update @t set value = floor (@sum_all/@h / @cnt)*@h

update t set value = value + @h
	,@i = id
--select *
from @t t
where id <= (@sum_all - @cnt * value ) /@h

update t1 set value = @sum_all - (select sum(value) from @t t2 where  t2.id <> @i+1 )
from @t t1
where id = @i+ 1

select * from @t


Вапрос ... может есть какие-то стандартные способы решения этой задачи
31 авг 12, 20:05    [13097460]     Ответить | Цитировать Сообщить модератору
 Re: Распределение суммы с "округлением" до половины  [new]
Serg_77m
Member

Откуда: Донецк
Сообщений: 237
Читатель неместный,

таблица целых чисел в базе есть? Стандартного решения не знаю, но это можно получить так:
declare @sum_all numeric(14,2),@cnt int,@h numeric(9,2)
select
  @sum_all=9.57,
  @cnt=7,
  @h=0.5

select a.number+1 as id,
  case when a.number>c2 then p1
       when a.number=c2 then @sum_all-p2*c2-(@cnt-c2-1)*p1
       else p2
  end as value
from master.dbo.spt_values a
  cross join (
    select *,
      p1+@h as p2,
      round((@sum_all-p1*@cnt)/@h-0.5,0) as c2
    from (
      select *,
        round(p/@h-0.5,0)*@h as p1
      from (select @sum_all/@cnt as p) b
   ) b
 ) b
where a.type='P' and a.number<@cnt
31 авг 12, 23:25    [13098125]     Ответить | Цитировать Сообщить модератору
 Re: Распределение суммы с "округлением" до половины  [new]
Serg_77m
Member

Откуда: Донецк
Сообщений: 237
Ах, да. Вместо round(что_то-0.5,0) лучше написать floor(что_то)
31 авг 12, 23:37    [13098157]     Ответить | Цитировать Сообщить модератору
 Re: Распределение суммы с "округлением" до половины  [new]
qwerty112
Guest
вот, вроде "делит" "честна" :))
declare @Heap	money			-- делимая сумма
declare @cnt	int			-- к-во желающих
declare @k	money			-- коэф."дробления"  (1->1, 2->0.5(1/2), 4->0.25(1/4), ..., 10->0.1(1/10), ... 100->0.01(1/100) )
--
set @Heap	=9.57
set @cnt		=7
set @k		=1
--
;with cte as (
select 1 as id, @Heap as start_Heap, @Heap/@cnt as xzz, ceiling(@Heap/@cnt*@k)/@k as value, @Heap-ceiling(@Heap/@cnt*@k)/@k as finish_Heap

union all

select cte.id+1, cte.finish_Heap, cte.finish_Heap/(@cnt-cte.id), ceiling(cte.finish_Heap/(@cnt-cte.id)*@k)/@k, cte.finish_Heap-ceiling(cte.finish_Heap/(@cnt-cte.id)*@k)/@k
from cte
where cte.id<@cnt
)

select id, 
case 
	when id=1 then value+a.finish_Heap
	else [value]
end as [value]
from cte
cross join (select finish_Heap from cte where id=@cnt)a

/* union который дальше просто для проверки */
union all

select null, 
sum(case 
	when id=1 then value+a.finish_Heap
	else [value]
end)
from cte
cross join (select finish_Heap from cte where id=@cnt)a

+
@k =1
id          value
----------- ---------------------
1           1,57
2           2,00
3           2,00
4           1,00
5           1,00
6           1,00
7           1,00
NULL        9,57

@k =2
id          value
----------- ---------------------
1           1,07
2           1,50
3           1,50
4           1,50
5           1,50
6           1,50
7           1,00
NULL        9,57

@k =10
id          value
----------- ---------------------
1           1,37
2           1,40
3           1,40
4           1,40
5           1,40
6           1,30
7           1,30
NULL        9,57
31 авг 12, 23:50    [13098203]     Ответить | Цитировать Сообщить модератору
 Re: Распределение суммы с "округлением" до половины  [new]
Читатель неместный
Guest
Спасибо!
Попытаюсь понять, как это вы так вот както пишете..
1 сен 12, 14:10    [13099320]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить