powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Посоветуйте по ЗАПРОСУ
25 сообщений из 37, страница 1 из 2
Посоветуйте по ЗАПРОСУ
    #39818833
Snickbw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FB25
Есть таблица два поля
Код: sql
1.
2.
3.
CREATE TABLE BAL (
    F_DATE  TIMESTAMP,
    F_KOL    NUMERIC(15,4));


Пример:

07.01.201815.6509.01.20185.520.01.201811.517.04.20181.6521.04.201812.627.04.20185.7508.05.20183.3508.05.201813.805.06.20182.2507.06.201835.507.06.20185.1527.08.201810.0502.10.201811.512.10.20180.0525.12.201811.0529.12.20181.35


Задача: необходимо получить результат с двумя значениями за указанный период.
1. Сумма всех значений поля F_KOL (проблем с этим нет)
2. Сумма чисел полученная по следующему алгоритму:
- если за календарный месяц есть хоть одна запись, то к итоговой сумме необходимо прибавить значение например 50
- если за календарный месяц нет ни одной записи, то из итоговой суммы необходимо вычесть значение например 30.
Пример:
Период: февраль 2018 - март 2019
Первая сумма - вопросов нет
Вторая сумма=-30-30+50+50+50-30+50-30+50-30+50-30-30-30=60
(-фев18-март18+апр18+май18+июнь18-июль18+авг18-сент18+окт18-нояб18+дек18-янв19-фев19-март19)

Вопрос: в какую сторону копать по ВТОРОЙ сумме?


-
Я бы изменил мир, но Бог не дает исходники...
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39818837
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
27.05.2019 15:11, Snickbw пишет:
> в какую сторону копать по ВТОРОЙ сумме?

SUM(CASE WHEN ... THEN ... END)
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39818896
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящий,

не копнёт, чувствую.

Snickbw, попробуй:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select extract(year from a.f_date), extract(month from a.f_date), count(*), sum(a.f_kol),
       sum(a.f_kol) + case count(*)
                      when 0 then -30
                      else 50
                      end
from bal a
where a.f_date between '2018-02-01' and '2019-03-31'
group by 1, 2
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39819091
Snickbw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXIМимопроходящий,
не копнёт, чувствую.


Вот и я столкнулся с той же проблемой, что и в вашем примере.
В таблице нет записей, за те месяцы, за которые необходимо вычесть 30 из второй суммы.
Как и у меня, так и вашем примере в результативной таблице нет группировочной записи по месяцам -фев18-март18-июль18-сент18-нояб18-янв19-фев19-март19. (см.пример данных в первом посте)
В итоге за эти отсутствующие месяцы из второй суммы ничего не вычитается.
Поэтому то я обратился на форум. Здесь как-то искусственно надо добавить в исходную таблицу записи за те месяцы которых нет в исходной таблице. Например через конструкцию
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
with ... as
(
select //добавить по одной записи по всем месяцам за период
...
union
select // все записи исходной таблицы
...
)


а уже потом имея записи по всем месяцам (в том числе и отсутствующих в исходной таблице) группировать по месяцам и годам с подсчётом двух сумм, при этом учитывая минус 30 и плюс 50 в зависимости от принадлежности записи к исскуственной таблице или исходной.
ИЛИ
сделать по другому:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
with tbl_1  as
(
select extract(year from a.f_date) as d1,
       extract(month from a.f_date) as d2,
       count(*)                           as d3  ,
       sum(a.f_kol)                 as d4,
       80                                 as d5
from bal a
where (a.f_date between '2018-02-01' and '2019-03-31')
group by 1, 2
union
select
0 as d1,
0 as d2,
0 as d3,
0 as d4,
datediff(month from cast('01.02.2018' as timestamp) to cast('31.03.2019' as timestamp))*(-30) as d5
from rdb$database
)
select
sum(d4),
sum(d5)
from tbl_1



З.Ы. 80 в поле D5 (это 50+30) и надо вычесть лишние 30, т.к. во второй таблице суммируются 30 за все месяцы за период
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39819180
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Snickbw,

да, проблема, не подумал. Тогда execute block (хранимка) c циклом по месяцам и годам, и запрос для каждого месяца.

Не знаю, можно ли посредством запроса к rdb$database получить список нужных дат, месяцев, годов.

Либо на клиенте обработать. На крайний случай.
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39819231
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тривиально вести таблицу-календарь и строить запрос левым джойном от неё не предлагать?
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39819297
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXIНе знаю, можно ли посредством запроса к rdb$database получить список нужных дат, месяцев, годов.Можно.
Но производственным календарём лучше.
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39819300
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Старый плюшевый мишка,

кто её будет вести? Уж лучше тогда GTT сделать, если по-другому никак. И опять же клиента никто не отменял, на нём можно отчёт добить отсутствующими данными.
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39819303
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXIкто её будет вести?проинитить разом лет на 100 вперед, а там или осел или падишах...
WildSeryНо производственным календарём лучше.раз в год по мере выхода переноса выходных подновлять.
KreatorXXIможно отчёт добить отсутствующими данными.это куда более хлопотно.
KreatorXXIУж лучше тогда GTT сделатьсмысл?
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39819333
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ivan_PisarevskyKreatorXXIкто её будет вести?проинитить разом лет на 100 вперед, а там или осел или падишах...


Крон на ночь -наше фсё.
Код: plsql
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.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
create or alter procedure FORM_CALENDAR
as
declare variable PERSTART date;
declare variable PEREND date;
declare variable PMONTH integer;
declare variable PYEAR integer;
declare variable NMONTH integer;
declare variable NYEAR integer;
declare variable STRDATE varchar(10);
declare variable STRMONTH varchar(8);
declare variable PNAME varchar(32);
declare variable DATES date;
declare variable DATEE date;
declare variable ENOUGH integer;
Begin Enough=0;
  While (Enough=0) Do
  begin
    Select First 1 PerStart, PerEnd, PMonth, PYear From Calendar
     Order By PerStart Desc
     Into :PerStart, :PerEnd, :PMonth, :PYear;
    if (PerStart>'today'+730) then
     Enough=1;
    else
     begin
       if (PMonth=12) then
        begin PYear=PYear+1; PMonth=1; NMonth=2; NYear=PYear; end
       else
        begin PMonth=PMonth+1;
          If (PMonth=12) then
           begin NMonth=1; NYear=PYear+1; end
          else
           begin NMonth=PMonth+1; NYear=PYear; end
        end
       if (PMonth<10) then
        StrDate='0'||Cast(PMonth As Char(1));
       else
        StrDate=Cast(PMonth As Char(2));
       Select RName From Monthes Where Code=:PMonth
       Into :StrMonth;
       StrDate=StrDate||'.'||Cast(PYear As Char(4));
       PName=StrDate||' '||StrMonth;
       StrDate='01.'||StrDate;
       DateS=Cast(StrDate As TimeStamp);

       if (NMonth<10) then
        StrDate='0'||Cast(NMonth As Char(1));
       else
        StrDate=Cast(NMonth As Char(2));
       StrDate='01.'||StrDate||'.'||Cast(NYear As Char(4));
       DateE=Cast(StrDate As TimeStamp);

       Insert Into Calendar (Name, PerStart, PerEnd, PMonth, PYear)
       Values (:PName,:DateS,:DateE,:PMonth,:PYear);
     end
  end
end



Дополнительные атрибуты периода - по вкусу.

Ivan_PisarevskyРаз в год по мере выхода переноса выходных подновлять.

Та у Думы семь пятниц на неделе, она ж всё о России днём и ночью думкает. В начале года одно надумкает, потом по ходу пару раз передумкает. Я исхожу из того, что лучше всех с любым делом справляется тот, кому оно надо. Кому из бухгалтеров первому понадобится воспользоваться неким автоматом на некий период для... замнём для ясности, но выходные он, автомат, учитывать обязан, тот на этот период и расставит выходные.
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39819423
vvvait
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
календарь не нужен, есть RDB$RELATIONS
21847529
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39819473
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vvvaitкалендарь не нужен, есть RDB$RELATIONS
21847529

Ога. Джойнить потом с этой хренью по каждому чиху, статусы периодов с точки зрения разных отделов к ней присобачивать и всё такое, а чё. Что бы ни делать, лишь бы за... за... устать, в общем. Самый правильный проход к зубам в стоматологических целях давно известен, классика.
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39819477
vvvait
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Старый плюшевый мишка, а если календаря нет, и прав на создание метаданных тоже
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39819482
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vvvaitа если нет прав на создание метаданных

Я бы посоветовал уволиться. А то потом начнут требовать поквартальные-помесячные-понедельные отчёты всех мастей и чтоб летало мухой. И виноват всегда будет сам понимаешь кто.
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39819669
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Старый плюшевый мишкаvvvaitкалендарь не нужен, есть RDB$RELATIONS
21847529

Ога. Джойнить потом с этой хренью по каждому чиху, статусы периодов с точки зрения разных отделов к ней присобачивать и всё такое, а чё. Что бы ни делать, лишь бы за... за... устать, в общем. Самый правильный проход к зубам в стоматологических целях давно известен, классика.

Получается, совсем красивого варианта нет. Вот мы производственный календарь ведём по отклонениям. Получается, прокол. Надо писать всё. Но у нас это (ведение производственного календаря) хотя бы оправдано. Функционал обширен и эти данные востребованы. В системах с ограниченным функционалом не так всё.
В других серверах какие-нибудь варианты есть?
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39819729
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

В пустой БД всегда можно генерировать счётчик.
Код: sql
1.
2.
3.
4.
5.
6.
select 1 n from rdb$database
union all
select 2 from rdb$database
...
union all
select 9 from rdb$database

затем перемножить его на самого себя сколько надо раз и дальше приклеить к нему дату
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39820665
Фотография Tonal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WildSery, KreatorXXI,

Можно и универсальный счётчик засандалить:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
with recursive
  numbers as (
    select 1 as n from RDB$DATABASE
    union all
    select n + 1 as n from numbers
    where n < 10
  )
select n from numbers
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39820668
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tonal,

И в чём же его универсальность, если он даже до 4 лет считать не умеет?
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39820679
Фотография Tonal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WildSery,
Да хоть до ста. ;)



$ aptitude show firebird3.0-server
Пакет: firebird3.0-server
Версия: 3.0.3.32900.ds4-3ubuntu6
Новый: да
Состояние: установлен
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39820739
Шавлюк Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tonal,

А так ?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
with recursive
  numbers as (
    select 1 n from rdb$database
    union all
    select n+1 from numbers
    where n < 1025
  )
select * from numbers



Чего только люди не сделают чтобы не писать процедуру...
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
create or alter procedure GET_ROWS (
    NUM integer)
returns (
    N integer)
AS
begin
  n = 0;
  while (n < num) do
  begin
    n = n + 1;
    suspend;
  end
end


...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39820742
Шавлюк Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну или вариант для дат
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
create or alter procedure GET_DATES (
    D1 date,
    D2 date)
returns (
    D date)
AS
begin
  d = d1-1;
  while (d < d2) do
  begin
    d = d+1;
    suspend;
  end
end

...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39820757
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TonalWildSery,
Да хоть до ста. ;)Зачем мне сто ДНЕЙ, если я спросил о четырёх ГОДАХ?
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39820817
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Шавлюк Евгений,

хорошая вещь. Возьму навооружение, может пригодиться.
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39820818
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

в моей БД уже давно такая процедура для итератора по датам
...
Рейтинг: 0 / 0
Посоветуйте по ЗАПРОСУ
    #39820823
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

И ты, Брут...
А вообще, кроме меня и МП, кто производственный календарь-то использует?
...
Рейтинг: 0 / 0
25 сообщений из 37, страница 1 из 2
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Посоветуйте по ЗАПРОСУ
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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