Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Посоветуйте по ЗАПРОСУ / 25 сообщений из 37, страница 1 из 2
27.05.2019, 15:11
    #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
27.05.2019, 15:15
    #39818837
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посоветуйте по ЗАПРОСУ
27.05.2019 15:11, Snickbw пишет:
> в какую сторону копать по ВТОРОЙ сумме?

SUM(CASE WHEN ... THEN ... END)
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
27.05.2019, 16:54
    #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
28.05.2019, 09:05
    #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
28.05.2019, 11:46
    #39819180
KreatorXXI
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посоветуйте по ЗАПРОСУ
Snickbw,

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

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

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

кто её будет вести? Уж лучше тогда GTT сделать, если по-другому никак. И опять же клиента никто не отменял, на нём можно отчёт добить отсутствующими данными.
...
Рейтинг: 0 / 0
28.05.2019, 14:13
    #39819303
Ivan_Pisarevsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посоветуйте по ЗАПРОСУ
KreatorXXIкто её будет вести?проинитить разом лет на 100 вперед, а там или осел или падишах...
WildSeryНо производственным календарём лучше.раз в год по мере выхода переноса выходных подновлять.
KreatorXXIможно отчёт добить отсутствующими данными.это куда более хлопотно.
KreatorXXIУж лучше тогда GTT сделатьсмысл?
...
Рейтинг: 0 / 0
28.05.2019, 14:42
    #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
28.05.2019, 16:32
    #39819423
vvvait
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посоветуйте по ЗАПРОСУ
календарь не нужен, есть RDB$RELATIONS
21847529
...
Рейтинг: 0 / 0
28.05.2019, 19:37
    #39819473
Старый плюшевый мишка
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посоветуйте по ЗАПРОСУ
vvvaitкалендарь не нужен, есть RDB$RELATIONS
21847529

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

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

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

Получается, совсем красивого варианта нет. Вот мы производственный календарь ведём по отклонениям. Получается, прокол. Надо писать всё. Но у нас это (ведение производственного календаря) хотя бы оправдано. Функционал обширен и эти данные востребованы. В системах с ограниченным функционалом не так всё.
В других серверах какие-нибудь варианты есть?
...
Рейтинг: 0 / 0
29.05.2019, 11:57
    #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
31.05.2019, 11:53
    #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
31.05.2019, 11:56
    #39820668
WildSery
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посоветуйте по ЗАПРОСУ
Tonal,

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



$ aptitude show firebird3.0-server
Пакет: firebird3.0-server
Версия: 3.0.3.32900.ds4-3ubuntu6
Новый: да
Состояние: установлен
...
Рейтинг: 0 / 0
31.05.2019, 13:23
    #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
31.05.2019, 13:26
    #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
31.05.2019, 13:46
    #39820757
WildSery
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посоветуйте по ЗАПРОСУ
TonalWildSery,
Да хоть до ста. ;)Зачем мне сто ДНЕЙ, если я спросил о четырёх ГОДАХ?
...
Рейтинг: 0 / 0
31.05.2019, 15:15
    #39820817
KreatorXXI
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Посоветуйте по ЗАПРОСУ
Шавлюк Евгений,

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

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

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


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