Нужно составить отчет
Нужно составить отчет
Проблема следующая.
Есть таблица
Create Table1
( ID Integer,
DStart Date,
DStop Date,
Hour_Work integer
)
Нужно получить отчет за период дат, то есть с клиента на сервер передаю 2 даты и на первое число каждого месяца из этого интервала нужно получить сумму часов.
Бьюсь два дня но ничего гениального придумать не смог. Может кто делал заранее спасибо.
Есть таблица
Create Table1
( ID Integer,
DStart Date,
DStop Date,
Hour_Work integer
)
Нужно получить отчет за период дат, то есть с клиента на сервер передаю 2 даты и на первое число каждого месяца из этого интервала нужно получить сумму часов.
Бьюсь два дня но ничего гениального придумать не смог. Может кто делал заранее спасибо.
Гениальный запрос я вчера написал и он отработал. Видимо ты меня не так понял попытаю описать задачу более подробно.
Есть период дат скажем с ’01.01.2008’ по ’01.04.2008’ так вот мне надо получить сначала
select count(Hour_Work)
from Table1 t
where t.DStart >= ’01.01.2008’ and t.DStart <= ’01.02.2008’
Потом следующий интервал из переданного т.е.
select count(Hour_Work)
from Table1 t
where t.DStart >= ’01.02.2008’ and t.DStart <= ’01.03.2008’
И так далее до ’01.04.2008’ так как это сделать в в одном запросе или ХП?
Может так будет понятней ибо вчера я спросил у товарища он тоже сначала так среагировал и прислал запрос типа where t.DStart >= ’01.01.2008’ and t.DStart <= ’01.04.2008’ но это мне не подходит т.к. мне нужно кол- во часов на первое число каждого месяца из интервала дат!
Есть период дат скажем с ’01.01.2008’ по ’01.04.2008’ так вот мне надо получить сначала
select count(Hour_Work)
from Table1 t
where t.DStart >= ’01.01.2008’ and t.DStart <= ’01.02.2008’
Потом следующий интервал из переданного т.е.
select count(Hour_Work)
from Table1 t
where t.DStart >= ’01.02.2008’ and t.DStart <= ’01.03.2008’
И так далее до ’01.04.2008’ так как это сделать в в одном запросе или ХП?
Может так будет понятней ибо вчера я спросил у товарища он тоже сначала так среагировал и прислал запрос типа where t.DStart >= ’01.01.2008’ and t.DStart <= ’01.04.2008’ но это мне не подходит т.к. мне нужно кол- во часов на первое число каждого месяца из интервала дат!
а Group By по месяцу не спасает?Matveih1 писал(а):Гениальный запрос я вчера написал и он отработал. Видимо ты меня не так понял попытаю описать задачу более подробно.
Есть период дат скажем с ’01.01.2008’ по ’01.04.2008’ так вот мне надо получить сначала
select count(Hour_Work)
from Table1 t
where t.DStart >= ’01.01.2008’ and t.DStart <= ’01.02.2008’
Потом следующий интервал из переданного т.е.
select count(Hour_Work)
from Table1 t
where t.DStart >= ’01.02.2008’ and t.DStart <= ’01.03.2008’
И так далее до ’01.04.2008’ так как это сделать в в одном запросе или ХП?
Может так будет понятней ибо вчера я спросил у товарища он тоже сначала так среагировал и прислал запрос типа where t.DStart >= ’01.01.2008’ and t.DStart <= ’01.04.2008’ но это мне не подходит т.к. мне нужно кол- во часов на первое число каждого месяца из интервала дат!
книжки почитай по sqlНе понимаю напишите пример
что-то типа
Код: Выделить всё
select SUM(Hour_Work)
from Table1 t
where t.DStart >= ’01.01.2008’ and t.DStart <= ’01.12.2008’
GROUP BY EXTRACT(month from t.DStart)
Причем тут таблица с 12 месяцами? Интервал дат может быть и несколько лет! Ладно как я уже сказал проблему я решил создав цикл в цикле. В первом цикле я получаю нужные мне даты, а во втором собственно запрос с использование этих дат. Вот и все и никого не посылал читать книги и не писал типа открой для себя SQL. А всякие таблички и группировки мне не подходят. Так что не так все просто как кажется на первый взгляд! И бросить фразу создай табличку типа тут и так все понятно это не решение! Если так все просто то напиши запрос который вернет данные в виде:
01.02.2008 40
01.03.2008 3
01.04.2008 0
01.05.2008 15
И так далее до конца интервала! А не пустые фразы!
01.02.2008 40
01.03.2008 3
01.04.2008 0
01.05.2008 15
И так далее до конца интервала! А не пустые фразы!
Matveih1 ну если у тебя все работает что ты еще хочешь, если периуд больше года может быть, то да календарик заводить.
а ты не кипятись, а то прийдет kdv с битой и оппа.
как вариант таблицу можно заменить на процедуру
ты ей интервал, а она тебе первые дни месяцов.
выигрыша никакого, но можно будет один код использовать в разных запросах.
а ты не кипятись, а то прийдет kdv с битой и оппа.
как вариант таблицу можно заменить на процедуру
ты ей интервал, а она тебе первые дни месяцов.
выигрыша никакого, но можно будет один код использовать в разных запросах.
Ды я не злюсь! Просто первый вопрос и такая реакция, какие то общие фразы, теперь и угрозы. Проблему решил сегодня утром, а тему завел вчера. Было интересно рассмотреть другие (альтернативные) пути решения, но видимо не судьба. И писать про группировку и сумму думаю не самый красивый ответ вы же не знаете мой уровень. Понятно, что у меня не такая табличка и записи там не такие, простоя попытался вынести основу вопроса, а не выкладывать всю БД.
какой вопрос такой ответ, про пустые месяцы в первом посте не обозначено.
альтернативно тебе уже 2 вариана привели "производственный календарь" и вынести цыкл в процедуру и джойн с ней делать. других вариантов и не будет.
а про уровень, воспользовался тегом [code] привел пример как ты сделал и что не устраивает и т.д.
прочитай свой первы пост и сделай вывод умеет ли человек пользоватьс групировкой или нет. а про sum ты сам привел примерчто не знаешь его =)
альтернативно тебе уже 2 вариана привели "производственный календарь" и вынести цыкл в процедуру и джойн с ней делать. других вариантов и не будет.
а про уровень, воспользовался тегом [code] привел пример как ты сделал и что не устраивает и т.д.
прочитай свой первы пост и сделай вывод умеет ли человек пользоватьс групировкой или нет. а про sum ты сам привел примерчто не знаешь его =)
"Производственный календарь" содержит месяца (и дни, но это не важно) за весь период данных, и обычно на год вперёд.
Потому запрос выглядит так:
Календарь используется для тучи разных запросов в отчётах и расчётов, потому без него плохо.
Но тоже можно. Вот мой пример (многократный запрос к Table1 плохо всё же, потому обращаюсь 1 раз, хотя так сложнее).
Потому запрос выглядит так:
Код: Выделить всё
select c.firstDateOfMonth, sum(t.Hour_Work)
from calendar c
left join Table1 t on extract(month from t.DStart) = c.month_
where t.DStart between '01.01.2007' and '01.03.2008'
Но тоже можно. Вот мой пример (многократный запрос к Table1 плохо всё же, потому обращаюсь 1 раз, хотя так сложнее).
Код: Выделить всё
execute block (DStart date, DEnd date)
returns (DateStart date, HSum int)
as
declare variable cur_date date;
declare variable hour_sum int;
begin
/* Находим 1й день месяца (если входная дата не 1-е) */
DateStart = DStart - extract(day from DStart) + 1;
for select (DStart - extract(day from DStart) + 1),
sum(Hour_Work)
from Table1
where DStart between :DStart and :DEnd
group by 1
into cur_date, hour_sum
do begin
HSum = 0;
while (DateStart < cur_date) do begin
suspend;
/* Прибавляем месяц */
DateStart = DateStart + 31;
DateStart = DateStart - extract(day from DateStart) + 1;
end
HSum = hour_sum;
suspend;
end
/* Тут долистываем месяца, на случай, если пустые в конце */
HSum = 0;
while (DateStart <= DEnd) do begin
suspend;
/* Прибавляем месяц */
DateStart = DateStart + 31;
DateStart = DateStart - extract(day from DateStart) + 1;
end
end
Re: Нужно составить отчет
По поводу пустых месяцев я писал
Не понимаю я альтернативы с календарем. Если не трудно напиши небольшой пример и если он окажется рабочим то я признаю ошибку и извинюсь.
По поводу SUM банально ошибся, описался ды как угодно суть вопроса была не в том как посчитать кол-во часов а как период разбить на несколько периодов. Как проще описать что я хотел не знаю.
там написано на 1 число каждого месяца из интервала.Matveih1 писал(а):с клиента на сервер передаю 2 даты и на первое число каждого месяца из этого интервала нужно получить сумму часов.
Не понимаю я альтернативы с календарем. Если не трудно напиши небольшой пример и если он окажется рабочим то я признаю ошибку и извинюсь.
По поводу SUM банально ошибся, описался ды как угодно суть вопроса была не в том как посчитать кол-во часов а как период разбить на несколько периодов. Как проще описать что я хотел не знаю.
для начало создаем календарик данные туда забиваем один раз (к примеру можно ежегодно на год вперед или один раз лет на 50) года и месяцы в итоге получаем таблицу в которой
и до посинениея
а потом запросом
ЗЫ календарик у себя не использую так как особеность моей системы
придумал все сейчас, ДикоСерж сейчас добавит критики
ЗЫЫ а вообще в календарике обычно все дни бывают тогда и запрос проще будет
Код: Выделить всё
mm yy
02 2008
03 2008
04 2008
05 2008
06 2008
07 2008
08 2008
а потом запросом
Код: Выделить всё
select cast('01.'||my.mm||'.'||my.yy as date) ,COALESCE(SUM(Hour_Work),0)
from Table1 t
left outer join my on my.mm = extract(month from t.DStart) and my.yy=extract(year from t.DStart)
where t.DStart >= ’01.01.2008’ and t.DStart <= ’01.12.2008’
GROUP BY my.fdate
придумал все сейчас, ДикоСерж сейчас добавит критики
ЗЫЫ а вообще в календарике обычно все дни бывают тогда и запрос проще будет
Это откуда взялось? Наверное, group by 1Attid писал(а):Код: Выделить всё
GROUP BY my.fdate
Кстати, я у себя в простом примере год не написал. Ну да ладно.