Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите оптимизировать запрос / 9 сообщений из 9, страница 1 из 1
22.03.2019, 11:11
    #39789946
Rphoenix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
Здравствуйте. Необходимо сделать отчет, в котором горизонтально месяцы, а вертикально параметры отбора.
я сделал вот такое (см. скрин). Там ID - номер строки, MOUNT - месяц, а COUNT - показатель. Все норм, только в столбик.
А мне нужно в строчку MOUNT вывести, а в столбик ID. На пересечении COUNTS. Это процедура CEL_POK_MOUNT(:YEARS) - берется за год.

Я хочу сделать вторую процедуру, которая будет выполнять правильно представление. Вот что я написал, но у меня цикл по запросу, а я хочу цикл внутри запроса, то есть за один проход разбивка по месяцам.

Код второй процедуры:

Код: sql
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.
begin
select MIN(ID)  from CEL_POK_MOUNT(:YEARS)
into :ID;
select MAX(ID) from CEL_POK_MOUNT(:YEARS)
into :MAXID;
 while (ID<=MAXID) do
  begin
    for select MOUNT, COUNTS
        from CEL_POK_MOUNT(:YEARS)
       where ID=ID
        into :MOUNT, :COUNTS
    do
    begin
    COUNTS=0;


        -- раскидаем значения по полям месяцев
        if (MOUNT = 1) then
          MOUNT1 = COUNTS;
        if (MOUNT = 2) then
          MOUNT2 = COUNTS;
        if (MOUNT = 3) then
          MOUNT3 = COUNTS;
        if (MOUNT = 4) then
          MOUNT4 = COUNTS;
        if (MOUNT = 5) then
          MOUNT5 = COUNTS;
        if (MOUNT = 6) then
          MOUNT6 = COUNTS;
        if (MOUNT = 7) then
          MOUNT7 = COUNTS;
        if (MOUNT = 8) then
          MOUNT8 = COUNTS;
        if (MOUNT = 9) then
          MOUNT9 = COUNTS;
        if (MOUNT = 10) then
          MOUNT10 = COUNTS;
        if (MOUNT = 11) then
          MOUNT11 = COUNTS;
        if (MOUNT = 12) then
          MOUNT12 = COUNTS;
end
        suspend;
        ID = ID + 1;
    end
    end
...
Рейтинг: 0 / 0
22.03.2019, 11:27
    #39789953
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
Rphoenix, в чём именно затруднение? Создай селективную процедуру с возвратом ID и 12 колонок COUNT с названием месяцев, в выборку добавь ORDER BY ID, MOUNT и также распихивай через операторы условия.
...
Рейтинг: 0 / 0
22.03.2019, 11:38
    #39789966
Vlad F
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
rdb_dev,

Проблема, очевидно, в counts = 0; первым оператором внутри цикла.))
...
Рейтинг: 0 / 0
22.03.2019, 11:50
    #39789970
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
Rphoenix,
вот как-то так...
Код: 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.
 RETURNS
 (
   ID ...,
   JAN ...,
   FEB ...,
   MAR ...,
   ...
 )
AS
  DECLARE CURR_ID ... DEFAULT NULL;
BEGIN
  FOR
      SELECT ID, MOUNT, COUNTS
        FROM CEL_POK_MOUNT(:YEARS)
        ORDER BY ID, MOUNT, COUNTS
        INTO: CURR_ID, MOUNT, COUNTS
    DO
      BEGIN
        IF (:ID IS NULL) THEN
          ID = CURR_ID;
        ELSE
          IF (:ID != :CURR_ID) THEN
            BEGIN
              SUSPEND;
              ID = CURR_ID;
              JAN = 0;
              FEB = 0;
              MAR = 0;
              .
              .
              .
            END
        IF (:MOUNT = 1) THEN JAN = COUNTS;
        ELSE IF (:MOUNT = 2) THEN FEB = COUNTS;
        ELSE IF (:MOUNT = 3) THEN MAR = COUNTS;
        .
        .
        .
      END
  IF (:ID IS NOT NULL) THEN SUSPEND;
END

...
Рейтинг: 0 / 0
22.03.2019, 12:00
    #39789973
court
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
Rphoenix
Код: sql
1.
2.
3.
4.
select MIN(ID)  from CEL_POK_MOUNT(:YEARS)
into :ID;
select MAX(ID) from CEL_POK_MOUNT(:YEARS)
into :MAXID;

А ты, что не можешь в одном запросе и MIN, и MAX получить ?
Или "чиста" дать серверу погрецца ? :)

И вообще, здесь всё решается одним запросом

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select 
   ID
   ,sum(case when MOUNT=1 then COUNTS end) as MOUNT1   
   ,sum(case when MOUNT=2 then COUNTS end) as MOUNT2   
   ...
   ,sum(case when MOUNT=12 then COUNTS end) as MOUNT12   

from CEL_POK_MOUNT(:YEARS)
group by
   ID
...
Рейтинг: 0 / 0
22.03.2019, 12:00
    #39789974
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
Vlad F, я особо не вникал, так как там бред понаписан. :)
...
Рейтинг: 0 / 0
22.03.2019, 12:07
    #39789978
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
court, во! Одним запросом ваще зачётно.
...
Рейтинг: 0 / 0
22.03.2019, 14:18
    #39790059
Rphoenix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
Большое спасибо! Тоже думал про группировку через ID, но не знал как, час просидел и ничего не получалось...
теперь буду знать, что через sum по case можно будет группировать.
...
Рейтинг: 0 / 0
22.03.2019, 14:18
    #39790063
Rphoenix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
" COUNTS=0;" да, не туда вставил, надо было в начало.
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите оптимизировать запрос / 9 сообщений из 9, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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