Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как лучше реализовать алгоритм / 5 сообщений из 5, страница 1 из 1
30.07.2013, 16:03
    #38348988
_ч_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как лучше реализовать алгоритм
Доброго всем дня.
Подскажите пожалуйста, как лучше всего организовать следующий алгоритм на Sql.

Есть таблица

Код: sql
1.
2.
3.
4.
5.
6.
declare	@t table (
	id bigint not null
   ,value decimal(23, 10) not null
   ,r decimal(23, 10) not null 
   ,source_id bigint null
   )



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

Ну, например:
Код: sql
1.
2.
3.
4.
5.
6.
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) на положительные.

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




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



Стало:
Код: sql
1.
2.
3.
4.
5.
6.
7.
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)
...
Рейтинг: 0 / 0
30.07.2013, 16:16
    #38349034
Ivan Durak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как лучше реализовать алгоритм
это у тебя фактически учет себестоимости по фифо. погугли. Кстати курсором будет лучше всего.
...
Рейтинг: 0 / 0
30.07.2013, 16:21
    #38349053
Mnior
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как лучше реализовать алгоритм
Транслятор SQL -> ASM ?

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

PS: А вообще такая задача тут на форуме решалась многократно. Но найти нереально, ибо также были невразумительно описаны.
К тому же задача не описывает множество исключительных ситуаций .
PPS: Гуманитарий детектед.
PPPS: Сколько можно решать свои проблемы за счёт других? На халяву.
...
Рейтинг: 0 / 0
30.07.2013, 16:55
    #38349137
_ч_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как лучше реализовать алгоритм
Mnior,

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

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


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


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

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
--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




Если у кого-то есть предложения по решению, пожалуйста, напишите.
...
Рейтинг: 0 / 0
30.07.2013, 17:44
    #38349233
Shakill
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как лучше реализовать алгоритм
_ч_,

посмотрите в этой теме похожая задача
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как лучше реализовать алгоритм / 5 сообщений из 5, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]