Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как лучше реализовать алгоритм  [new]
_ч_
Member

Откуда:
Сообщений: 1427
Доброго всем дня.
Подскажите пожалуйста, как лучше всего организовать следующий алгоритм на Sql.

Есть таблица

declare	@t table (
	id bigint not null
   ,value decimal(23, 10) not null
   ,r decimal(23, 10) not null 
   ,source_id bigint null
   )


Таблица содержит отрицательные и положительные значения.

Ну, например:
insert into @t(id, value, r, source_id)
select 1, -50, -50, null
union all
select 2, -50, -50, null
union all
select 3, 125, 125, null


Надо отрицательные значения закрыть положительными и вставить ссылку (source_id) на положительные.

Результат должен быть:
select 1, -50, 0, 3
union all
select 2, -50, 0, 3
union all
select 3, 125, 25, null



Если положительных баллов не хватает, то отрицательные надо разбить на отдельные записи.
Например, было:
select 1, -50, -50, null
union all
select 2, -50, -50, null
union all
select 3, 75, 75, null


Стало:
select 1, -50, 0, 3
union all
select 2, -25, 0, 3
union all
select 3, 75, 0, null
union all
select 4, -25, -25, null


Подскажите пожалуйста, как мне реализовать алгоритм максимально эффективно и без использования цикла?

Version:
Microsoft SQL Server 2012 - 11.0.2100.60 (X64)
30 июл 13, 16:03    [14638326]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше реализовать алгоритм  [new]
Ivan Durak
Member

Откуда: Minsk!!!
Сообщений: 3618
это у тебя фактически учет себестоимости по фифо. погугли. Кстати курсором будет лучше всего.
30 июл 13, 16:16    [14638446]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше реализовать алгоритм  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Транслятор SQL -> ASM ?

Вообще-то SQL декларативный язык, он решает задачи предметной области, а не сферические алгоритмы в вакууме.
Предметной задачи не было предъявлено, следовательно проблемы нет, следовательно топик надо прикрыть.
Разве нет?

PS: А вообще такая задача тут на форуме решалась многократно. Но найти нереально, ибо также были невразумительно описаны.
К тому же задача не описывает множество исключительных ситуаций.
PPS: Гуманитарий детектед.
PPPS: Сколько можно решать свои проблемы за счёт других? На халяву.
30 июл 13, 16:21    [14638490]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше реализовать алгоритм  [new]
_ч_
Member

Откуда:
Сообщений: 1427
Mnior,

Ну это Вы глупость написали, уважаемый.

На счет постановки задачи, как мне еще её написать?
Что Вам лично не понятно в такой постановке:
Надо отрицательные значения закрыть положительными и вставить ссылку (source_id) на положительные.


Ivan Durak, спасибо, гляну.


Пока сделал так, но с циклом и нет уверенности в том, что это самый эффективный способ решения. К сожалению

--insert into @t(id, value, r, source_id) select 1, -50, -50, null union all select 2, -50, -50, null union all select 3, 25, 25, null
insert into @t(id, value, r, source_id) select 1, -50, -50, null union all select 2, -50, -50, null union all select 3, 125, 125, null

declare @t_temp table (id bigint null   ,value decimal(23, 10) not null   ,r decimal(23, 10) not null    ,source_id bigint null, old_id bigint null)

while exists(select 1 from @t where r > 0) and exists(select 1 from @t where r < 0)
begin

;with t(id, value, r, source_id, id_old)
as
(
select a.id, a.value, case when a.r+b.r > 0 then 0 else a.r+b.r end, b.id as source_id, null from (select row_number() over(order by id) n1, * from @t where r < 0)a
join (select row_number() over(order by id) n1, * from @t where r > 0)b on a.n1 = b.n1
)
insert into @t_temp(id, value, r, source_id, old_id)
select t1.id, t1.value, t1.r+isnull(t.value, 0) as r, t1.source_id, null from @t t1
left join t on t.source_id = t1.id
where t1.id not in (select id from t)
union all
select id, value, 0 as r, source_id, null from t
union all 
select null as id, t.value-t.r, t.value-t.r, null as source_id, id from t
where t.r <> 0

delete @t

insert into @t(id, value, r, source_id, old_id)
select id, value, r, source_id, old_id from @t_temp

delete @t_temp

end

select * from @t



Если у кого-то есть предложения по решению, пожалуйста, напишите.
30 июл 13, 16:55    [14638764]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше реализовать алгоритм  [new]
Shakill
Member

Откуда: мск
Сообщений: 1880
_ч_,

посмотрите в этой теме похожая задача
30 июл 13, 17:44    [14639062]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить