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

Откуда: Питер
Сообщений: 1402
select *
into  #test
from (
select 1 as 'id',100 as 'Вход',50 as 'Выход',100 as 'Резерв на начало',150 as 'Резерв на конец'
union
select 2,100,130,150,120
union
select 3,50,10,120,160
union
select 4,10,30,160,140) as t

select * from #test
order by id

Суть вопроса в следующем: 'Резерв на начало' должен быть все время равен 'Резерву на конец' предыдущего дня(id)
Резерв на конец считается как ('Вход'-'Выход')+'Резерв на начало'.
При изменении данных(у id=1 если изменился вход, то резервы придется пересчитать для всех следующих id) приходится каждый раз пересчитывать резервы курсором.
Может еще кто какие варианты подскажет.
12 июл 11, 17:12    [10963204]     Ответить | Цитировать Сообщить модератору
 Re: Текущие/предыдущее значения  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Для каждой строки [Резерв на конец]=SUM('Вход')-SUM('Выход') для id<=[id текущей строки]+[Резерв на начало для первой строки]
Это выражение легко оформить в виде коррелированного подзапроса в списке SELECTа.
Разве что сообразить, надо ли учитывать текущую строку в сумме входа или выхода (с помощью CASE)
Подтормаживать будет.

Корректнее, наверно, считать не в порядке id, а в порядке возрастания даты, которая, конечно, должна быть.

P.S. Может, я ошибаюсь?
12 июл 11, 17:23    [10963303]     Ответить | Цитировать Сообщить модератору
 Re: Текущие/предыдущее значения  [new]
+5 коп
Guest
linke,

нормальный вариант, вот только стоит избавиться от "Резерв на начало" или "резерв на конец" - одно из этих полей можно рассчитать по трем остальным..
дату (ну или другое поле, задающее порядок истории изменений) обязательно вводить, а лучше (если даты) - то период действия записи (если часто придется лазить в "исторические даты") так, чтобы дата_конца предидущей записи была равна дата_конца последующей.

Ну а при правках "задним числом" так и придется все пересчитывать

просто сравните соотношения количества
запросов на изменение "задним числом"
запросов на получение "текущего состояния"
запросов на получение данных "на дату" из истории
(а в большинстве систем 2 и 3 - это одни и те же запросы)

только в случае, когда 1 и 3 составляют меньше сотых процента от 2 - применяют отдельно таблицу "резера" и изменений, при этом получая "резерв" из истории вычисляя по таблице изменений.
12 июл 11, 17:37    [10963423]     Ответить | Цитировать Сообщить модератору
 Re: Текущие/предыдущее значения  [new]
+5 коп
Guest
вдогонку, про последний вариант, в этом случае таблицу "резерва" закрывают на изменение из приложения и изменяют триггерами на таблице "изменений"
12 июл 11, 17:39    [10963441]     Ответить | Цитировать Сообщить модератору
 Re: Текущие/предыдущее значения  [new]
linke
Member

Откуда: Питер
Сообщений: 1402
iap
Для каждой строки [Резерв на конец]=SUM('Вход')-SUM('Выход') для id<=[id текущей строки]+[Резерв на начало для первой строки]
Это выражение легко оформить в виде коррелированного подзапроса в списке SELECTа.
Разве что сообразить, надо ли учитывать текущую строку в сумме входа или выхода (с помощью CASE)
Подтормаживать будет.

Корректнее, наверно, считать не в порядке id, а в порядке возрастания даты, которая, конечно, должна быть.

P.S. Может, я ошибаюсь?

Нет, не ошибаетесь.Все так.

Только одного обновления резерва на конец не достаточно, что делать с резервом на начало в таком случае?
12 июл 11, 17:40    [10963451]     Ответить | Цитировать Сообщить модератору
 Re: Текущие/предыдущее значения  [new]
smls
Guest
linke,

select t.id,t.vh,t.vyh,coalesce(qq.sm,t.rb) rb,
(select sum(vh)-sum(vyh) from #test where id<=t.id) + (select rb from #test where id=1 ) re
from #test t left join
(select t1.id,(select sum(vh)-sum(vyh) from #test where id<=t1.id) + (select rb from #test where id=1 ) sm
from #test t1 ) qq on t.id=qq.id+1
13 июл 11, 12:01    [10966484]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить