![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Срок задолженности [fb 1.5]
makz © (2007-01-10 07:21:00)Есть таблица:
CREATE TABLE DOK (
ID INTEGER NOT NULL,
ID_ST INTEGER NOT NULL,
SUMM DECIMAL(15,2) NOT NULL,
DOKDATE DATE NOT NULL
);
В нее добавляются записи с SUMM > 0 и < 0. Вычисляются суммы по разным ST_ID:
select sum(SUMM) from DOK
group by ID_ST
(ID_ST - внешний ключ). Для вычисления срока в течение которого sum(SUMM) <0 используется ХП. Есть ли возможность обойтись без ХП, одним запросом? Прошу прощения, если невнятно задал вопрос, долго уже мучаюсь :).
Павел Калугин (2007-01-16 19:11:00) [1]> [30] Johnmen (16.01.07 18:43)
подозрение верное. ибо и ib почти не работал...
Johnmen (2007-01-16 18:43:00) [2]
> Павел Калугин © (16.01.07 18:36) [29]
Прямо из "курсора" берём, обрабатываем, возвращаем из ХП.
SELECT FROM ХП возвратит нам результирующий набор данных.
ЗЫ
Есть подозрение, что ты не знаешь, как работать с ХП, возвращающей набор данных. Читать здесь ibase.ru
Павел Калугин (2007-01-16 18:36:00) [3]> [28] Johnmen (16.01.07 18:28)
Окончательно Вы меня запутали понял.
есть данные
дата | сумма | вид операции
надо получить в виде
дата | сумма до операции | сумма операции | сумма после операции
прямой обход? то есть прямо в курсоре и наружу отдавать?
Johnmen (2007-01-16 18:28:00) [4]
> Павел Калугин © (16.01.07 18:16) [27]
> то есть нужный период отбираем во временную таблицу
> и по ней в курсоре расставляем вход исход остатки по операциям?
Ни о каких вр.таблицах речь не идёт!
Все сформированные конечные записи получаем на выходе ХП.
Павел Калугин (2007-01-16 18:16:00) [5]> [26] Johnmen (16.01.07 18:06)
> Тогда пиши ХП, где прямой обход записей SELECT * From Table
> ORDER BY дата.
> И, ес-но, логическая и расчётная обработка.
> Это будет максимально быстро.
то есть нужный период отбираем во временную таблицу и по ней в курсоре расставляем вход исход остатки по операциям? и это будет максимально быстро? но почему это будет быстрее запроса?
Johnmen (2007-01-16 18:06:00) [6]
> Павел Калугин © (16.01.07 17:41) [25]
Тогда пиши ХП, где прямой обход записей SELECT * From Table ORDER BY дата.
И, ес-но, логическая и расчётная обработка.
Это будет максимально быстро.
Павел Калугин (2007-01-16 17:41:00) [7]> [24] Johnmen (16.01.07 17:35)
да 23 это так к слову о внимательности
если по поводу
> [18] Павел Калугин © (16.01.07 16:45)
то важно бысттро и эффективно построить отчет
Johnmen (2007-01-16 17:35:00) [8]
> Павел Калугин © (16.01.07 16:45) [18]
Определись, что важнее - быстрее и понятнее, но писать ХП, или медленнее и менее понятно, но один многоэтажный запрос.
Вычисляемое поле делать не советую. Т.к. это вопреки нормализации, а самое главное - тормоза при выборке, да и вообще такое поле создать не получится ИМХО потому, что будет селективная выборка из себя самой.
Павел Калугин (2007-01-16 17:16:00) [9]> [22] stone © (16.01.07 17:13)
> [10] makz © (11.01.07 11:58)
> может сделать что-ли вычислимое поле или вью с нарастаюшими
> итогами?
stone (2007-01-16 17:13:00) [10]нет, только как процедуру, view, насколько я помню не поддерживает объявления переменных
Павел Калугин (2007-01-16 17:09:00) [11]> [19] stone © (16.01.07 17:05)
и это можно во view завернуть?
stone (2007-01-16 17:06:00) [12]в догонку, сорри это TSQL, на сабж не посмотрел
stone (2007-01-16 17:05:00) [13]declare @t table(dt int, sm int, v int, rest int)
insert into @t
select 0, 10, +1, null
union all
select 1, 10, +1, null
union all
select 2, 11, -1, null
union all
select 3, 12, +1, null
union all
select 4, 13, +1, null
union all
select 5, 14, -1, null
union all
select 6, 14, +1, null
declare @rest int
set @rest = 0
update @t set @rest = rest = @rest + sm*v
select * from @t
Павел Калугин (2007-01-16 16:45:00) [14]> [17] Johnmen (16.01.07 15:38)
есть данные по операциям (проводки грубо говоря) вида
дата сумма вид_опер
0 10 +1
1 10 +1
2 11 -1
3 12 +1
4 13 +1
5 14 -1
6 14 +1
с даты 2 по дату 5 надо получить отчет вида
входящий остаток на начало 10*1+10*1 = 20
Дата Вх остаток Сумма операции Исх остаток
2 20 11 20+11*-1 = 9
3 9 12 9+12*+1 = 21
4 21 13 21+13*+1 = 34
5 34 14 34+14*-1 = 20
исходящий остаток на окончание 20
в курсоре (цикле) я такое собирал неоднократно. Но слышал (читал) что можно собрать одним запросом. как? может известно?
select (select sum(сумма*вид_опер) from таблица as T where Старт<=T.дата <R.дата),
R.сумма,
(select sum(T.сумма*T.вид_опер) from таблица as T where СтартПериода<=T.дата <R.дата)+ R.сумма*вид_опер
from таблица as R
where R.дата в периоде отчета
ну вроде можно и так но жутко неэффективно, как мне кажется..
Johnmen (2007-01-16 15:38:00) [15]
> Павел Калугин © (16.01.07 11:47) [15]
Уточни, что конкретно надо. Желательно формализованно.
Павел Калугин (2007-01-16 11:48:00) [16]> [15] Павел Калугин © (16.01.07 11:47)
когда-то делал нечто подобное но как корова языком слизала.. :(
Павел Калугин (2007-01-16 11:47:00) [17]> [14] Johnmen © (13.01.07 14:36)
Прости, не напомнишь как в одном запросе входящий исходящий остаток по операциям поднять?
Johnmen (2007-01-13 14:36:00) [18]
> makz ©
Нарастающий итог можно посчитать так
SELECT A.DOKDATE, SUM(B.SUMM) FROM DOK A, DOK B
WHERE B.DOKDATE<=A.DOKDATE
GROUP BY A.DOKDATE
а дальше в ХП обойти в цикле.
ЮЮ (2007-01-11 12:12:00) [19]С другой стороны, если записи поступают строго в порядке возрастания DOKDATE DATE и не корректируются в дальнейшем, то текущую на момент внесения записи задолжность можно вычислить и хранить в поле этой же записи
ЮЮ (2007-01-11 12:10:00) [20]Может это и противоречит теории СУБД, но если данную процедуру требуется выполнять постоянно и она занимает много времени, то можно создать таблицу нарастающих итогов и корректровать её в триггерах таблицы DOK