Страница 1 из 1
Запрос для нарастающего итога
Добавлено: 04 дек 2007, 11:14
kozer
Здраствуйте, уважаемые спецы.
Сервер FB 1.5.
В таблице есть 3 поля:
Id - первичный ключ (INTEGER),
DateDoc - дата документа (DATE),
Value - значение (INTEGER).
Нужно сделать запрос (procedure или view), в котором в 4-ом поле будет значение поля Value наростающим итогом за месяц. Кто-нибуть сталкивался с такой задачей?
Добавлено: 04 дек 2007, 11:56
Dimitry Sibiryakov
Stored Procedure - наиболее быстрый и простой путь. Второй по простоте, но первый по скорости - воспользоваться средствами самого отчетника.
Добавлено: 04 дек 2007, 12:01
kozer
Нарастающий итог нужен, в первую очередь, для отображения в гриде. А в репорте реализовать без проблем...
Добавлено: 04 дек 2007, 12:58
CyberMax
так?
Код: Выделить всё
select
...,
(select sum(t2.value) from some_table t2 where
(extract(year from t1.datedoc) = extract(year from t2.datedoc))
and (extract(month from t1.datedoc) = extract(month from t2.datedoc))
and (t2.datedoc < t1.date_doc))
from
some_table t1
Добавлено: 04 дек 2007, 13:09
kozer
Спасибо большое, работает!
Добавлено: 04 дек 2007, 14:54
CyberMax
Можешь добавить в таблицы документов поле периода. Тип INTEGER, структура - YYYYMM. Зависит от DateDoc и обновляется либо на клиенте либо в триггере. Позволяет существенно упростить выборку по месяцу и группировку по нему же:
вместо
Код: Выделить всё
WHERE DATEDOC BETWEEN '01.12.2007' AND '31.12.2007'
и
Код: Выделить всё
GROUP BY EXTRACT(YEAR FROM DATEDOC), EXTRACT(MONTH FROM DATEDOC)'
получаем
и
Ну и плюс прирост скорости выполнения.
Добавлено: 04 дек 2007, 15:37
belov-evgenii
А может что-нибудь типа этого?
Код: Выделить всё
select
ip.fio_spi as pristav,
case when extract(month from current_timestamp) >= 1 then sum(case when ip.date_ip_in < '01.02.2007' then 1 else 0 end) else 0 end as january,
case when extract(month from current_timestamp) >= 2 then sum(case when ip.date_ip_in < '01.03.2007' then 1 else 0 end) else 0 end as february,
case when extract(month from current_timestamp) >= 3 then sum(case when ip.date_ip_in < '01.04.2007' then 1 else 0 end) else 0 end as march,
case when extract(month from current_timestamp) >= 4 then sum(case when ip.date_ip_in < '01.05.2007' then 1 else 0 end) else 0 end as april,
case when extract(month from current_timestamp) >= 5 then sum(case when ip.date_ip_in < '01.06.2007' then 1 else 0 end) else 0 end as may,
case when extract(month from current_timestamp) >= 6 then sum(case when ip.date_ip_in < '01.07.2007' then 1 else 0 end) else 0 end as juny,
case when extract(month from current_timestamp) >= 7 then sum(case when ip.date_ip_in < '01.08.2007' then 1 else 0 end) else 0 end as july,
case when extract(month from current_timestamp) >= 8 then sum(case when ip.date_ip_in < '01.09.2007' then 1 else 0 end) else 0 end as august,
case when extract(month from current_timestamp) >= 9 then sum(case when ip.date_ip_in < '01.10.2007' then 1 else 0 end) else 0 end as september,
case when extract(month from current_timestamp) >= 10 then sum(case when ip.date_ip_in < '01.11.2007' then 1 else 0 end) else 0 end as october,
case when extract(month from current_timestamp) >= 11 then sum(case when ip.date_ip_in < '01.12.2007' then 1 else 0 end) else 0 end as november,
case when extract(month from current_timestamp) >= 12 then sum(case when ip.date_ip_in < '01.01.2008' then 1 else 0 end) else 0 end as december
from ip
group by 1
Добавлено: 04 дек 2007, 15:57
kozer
Нет, спасибо. Насколько я понял, у Вас выводится поле - название месяца и подсчитывается колличество чего-то там за месяц. Немного не то. Уважаемый
CyberMax предложил хороший работающий вариант. Я сделал эту задачу при помощи процедур, но предложеный вариант элегантней.
Код: Выделить всё
CREATE PROCEDURE P_GAS
returns (
id integer,
data date,
fisher integer
)
as
declare variable vYear integer;
declare variable vMonth integer;
begin
total = 0;
vYear = 0;
vMonth = 0;
for
select id,
data,
fisher
from gas
order by data
into :id,
:data,
:fisher
do
begin
if ((EXTRACT(year from data) <> vYear) or (EXTRACT(month from data) <> vMonth)) then
begin
total = 0;
vYear = EXTRACT(year from data);
vMonth = EXTRACT(month from data);
end
total = total + :fisher;
suspend;
end
end
Добавлено: 05 дек 2007, 08:48
Tonal
Можно ещё на контекстных переменных.
Добавлено: 05 дек 2007, 10:31
WildSery
Tonal писал(а):Можно ещё на контекстных переменных.
В 1.5 ещё нельзя
