powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Запрос по нескольким условиям GROUP BY HAVING
8 сообщений из 8, страница 1 из 1
Запрос по нескольким условиям GROUP BY HAVING
    #39947937
Alexander Warlord
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Уважаемые форумчане, приветствую!

Есть запрос по нескольким UNION с разными условиями группировки. Тут их 4, но должно быть больше:

Код: 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.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
SELECT
    REG_ID AS REG_ID,
    REGION AS REGION,
    COMM_NAME AS COMM_NAME,
    TRAFIK_NAME AS TRAFIK_NAME,
    TRPL_NAME AS TRPL_NAME,
    COUNT(UNIQUE SUBS_ID) AS KOLVO
FROM
(SELECT
    bs.REG_ID AS REG_ID,
    bs.REGION AS REGION,
    zttc.COMM_NAME AS COMM_NAME,
    zttt.TRAFIK_NAME AS TRAFIK_NAME,
    ztt.TRPL_NAME AS TRPL_NAME,
    cll.SUBS_ID AS SUBS_ID,
    COUNT(cll.CALL_ID) AS KOLVO
FROM
    SUBS_HISTORY sh,
    Z_TARIFF_TYPE ztt,
    Z_TARIFF_TYPE_COMM zttc,
    Z_TARIFF_TYPE_TRAFIK zttt,
    BASE_STATIONS bs,
    CALL_D_03_2020 clld,
    CALL_03_2020 cll
WHERE
    cll.OWNER_CALL_ID = 0
    AND sh.SUBS_ID = cll.SUBS_ID
    AND cll.CALL_ID = clld.CALL_ID
    AND clld.CELL_A = bs.CELL_ID
    AND ztt.TRPL_ID = sh.TRPL_ID
    AND ztt.COMM = zttc.COMM
    AND ztt.TRAF = zttt.TRAF
    AND zttt.TRAF NOT IN (3, 5)
    AND cll.SERV_ID <> 166
    AND cll.START_TIME BETWEEN sh.STIME AND sh.ETIME - 1/86400
GROUP BY cll.SUBS_ID, bs.REG_ID, bs.REGION, zttc.COMM_NAME, zttt.TRAFIK_NAME, ztt.TRPL_NAME HAVING COUNT(cll.CALL_ID) >= 20
UNION ALL
SELECT
    bs.REG_ID AS REG_ID,
    bs.REGION AS REGION,
    zttc.COMM_NAME AS COMM_NAME,
    zttt.TRAFIK_NAME AS TRAFIK_NAME,
    ztt.TRPL_NAME AS TRPL_NAME,
    cll.SUBS_ID AS SUBS_ID,
    COUNT(cll.CALL_ID) AS KOLVO
FROM
    SUBS_HISTORY sh,
    Z_TARIFF_TYPE ztt,
    Z_TARIFF_TYPE_COMM zttc,
    Z_TARIFF_TYPE_TRAFIK zttt,
    BASE_STATIONS bs,
    CALL_D_03_2020 clld,
    CALL_03_2020 cll
WHERE
    cll.OWNER_CALL_ID = 0
    AND sh.SUBS_ID = cll.SUBS_ID
    AND cll.CALL_ID = clld.CALL_ID
    AND clld.CELL_A = bs.CELL_ID
    AND ztt.TRPL_ID = sh.TRPL_ID
    AND ztt.COMM = zttc.COMM
    AND ztt.TRAF = zttt.TRAF
    AND zttt.TRAF = 5
    AND cll.SERV_ID = 166
    AND cll.START_TIME BETWEEN sh.STIME AND sh.ETIME - 1/86400
GROUP BY cll.SUBS_ID, bs.REG_ID, bs.REGION, zttc.COMM_NAME, zttt.TRAFIK_NAME, ztt.TRPL_NAME HAVING COUNT(cll.CALL_ID) >= 500
UNION ALL
SELECT
    bs.REG_ID AS REG_ID,
    bs.REGION AS REGION,
    zttc.COMM_NAME AS COMM_NAME,
    zttt.TRAFIK_NAME AS TRAFIK_NAME,
    ztt.TRPL_NAME AS TRPL_NAME,
    cll.SUBS_ID AS SUBS_ID,
    COUNT(cll.CALL_ID) AS KOLVO
FROM
    SUBS_HISTORY sh,
    Z_TARIFF_TYPE ztt,
    Z_TARIFF_TYPE_COMM zttc,
    Z_TARIFF_TYPE_TRAFIK zttt,
    BASE_STATIONS bs,
    CALL_D_03_2020 clld,
    CALL_03_2020 cll
WHERE
    cll.OWNER_CALL_ID = 0
    AND sh.SUBS_ID = cll.SUBS_ID
    AND cll.CALL_ID = clld.CALL_ID
    AND clld.CELL_A = bs.CELL_ID
    AND ztt.TRPL_ID = sh.TRPL_ID
    AND ztt.COMM = zttc.COMM
    AND ztt.TRAF = zttt.TRAF
    AND zttt.TRAF = 3
    AND cll.SERV_ID <> 166
    AND cll.START_TIME BETWEEN sh.STIME AND sh.ETIME - 1/86400
GROUP BY cll.SUBS_ID, bs.REG_ID, bs.REGION, zttc.COMM_NAME, zttt.TRAFIK_NAME, ztt.TRPL_NAME HAVING COUNT(cll.CALL_ID) >= 100
UNION ALL
SELECT
    bs.REG_ID AS REG_ID,
    bs.REGION AS REGION,
    zttc.COMM_NAME AS COMM_NAME,
    zttt.TRAFIK_NAME AS TRAFIK_NAME,
    ztt.TRPL_NAME AS TRPL_NAME,
    cll.SUBS_ID AS SUBS_ID,
    COUNT(cll.CALL_ID) AS KOLVO
FROM
    SUBS_HISTORY sh,
    Z_TARIFF_TYPE ztt,
    Z_TARIFF_TYPE_COMM zttc,
    Z_TARIFF_TYPE_TRAFIK zttt,
    BASE_STATIONS bs,
    CALL_D_03_2020 clld,
    CALL_03_2020 cll
WHERE
    cll.OWNER_CALL_ID = 0
    AND sh.SUBS_ID = cll.SUBS_ID
    AND cll.CALL_ID = clld.CALL_ID
    AND clld.CELL_A = bs.CELL_ID
    AND ztt.TRPL_ID = sh.TRPL_ID
    AND ztt.COMM = zttc.COMM
    AND ztt.TRAF = zttt.TRAF
    AND zttt.TRAF = 3
    AND cll.SERV_ID = 166
    AND cll.START_TIME BETWEEN sh.STIME AND sh.ETIME - 1/86400
GROUP BY cll.SUBS_ID, bs.REG_ID, bs.REGION, zttc.COMM_NAME, zttt.TRAFIK_NAME, ztt.TRPL_NAME HAVING COUNT(cll.CALL_ID) >= 1000)
GROUP BY REG_ID, REGION, COMM_NAME, TRAFIK_NAME, TRPL_NAME
ORDER BY REG_ID, COMM_NAME, TRPL_NAME



Можно ли как-то изменить запрос, чтобы не добавлять для каждого условия HAVING COUNT(cll.CALL_ID) >= ... - новый подзапрос UNION?

Условия:
1. TRAF NOT IN (3, 5)
SERV_ID <> 166
COUNT(cll.CALL_ID) >= 20
2. TRAF NOT IN (3, 5)
SERV_ID = 166
COUNT(cll.CALL_ID) >= 500
3. TRAF NOT = 3
SERV_ID <> 166
COUNT(cll.CALL_ID) >= 100
3. TRAF NOT = 3
SERV_ID = 166
COUNT(cll.CALL_ID) >= 1000
и т.д.

Чтобы в одном запросе были учтены все условия.
...
Рейтинг: 0 / 0
Запрос по нескольким условиям GROUP BY HAVING
    #39947953
PuM256
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alexander Warlord,

Так тут не только в HAVING COUNT дело, тут ещё и фильтрация перед группировкой разная.

Можно попробовать переписать в таком ключе:
Код: 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.
SELECT
    REG_ID AS REG_ID,
    REGION AS REGION,
    COMM_NAME AS COMM_NAME,
    TRAFIK_NAME AS TRAFIK_NAME,
    TRPL_NAME AS TRPL_NAME,
    COUNT(UNIQUE SUBS_ID) AS KOLVO
FROM
(
Select * From (
SELECT
    bs.REG_ID AS REG_ID,
    bs.REGION AS REGION,
    zttc.COMM_NAME AS COMM_NAME,
    zttt.TRAFIK_NAME AS TRAFIK_NAME,
    ztt.TRPL_NAME AS TRPL_NAME,
    cll.SUBS_ID AS SUBS_ID,
    COUNT(Case 
	When zttt.TRAF NOT IN (3, 5) And cll.SERV_ID <> 166
		Then cll.CALL_ID
	Else Null End) AS KOLVO1,
    COUNT(Case 
	When zttt.TRAF NOT IN (3, 5) And cll.SERV_ID = 166
		Then cll.CALL_ID
	Else Null End) AS KOLVO2,
    COUNT(Case 
	When zttt.TRAF = 3 And cll.SERV_ID <> 166
		Then cll.CALL_ID
	Else Null End) AS KOLVO3,
    COUNT(Case 
	When zttt.TRAF = 3 And cll.SERV_ID = 166
		Then cll.CALL_ID
	Else Null End) AS KOLVO4
FROM
    SUBS_HISTORY sh,
    Z_TARIFF_TYPE ztt,
    Z_TARIFF_TYPE_COMM zttc,
    Z_TARIFF_TYPE_TRAFIK zttt,
    BASE_STATIONS bs,
    CALL_D_03_2020 clld,
    CALL_03_2020 cll
WHERE
    cll.OWNER_CALL_ID = 0
    AND sh.SUBS_ID = cll.SUBS_ID
    AND cll.CALL_ID = clld.CALL_ID
    AND clld.CELL_A = bs.CELL_ID
    AND ztt.TRPL_ID = sh.TRPL_ID
    AND ztt.COMM = zttc.COMM
    AND ztt.TRAF = zttt.TRAF
    AND cll.START_TIME BETWEEN sh.STIME AND sh.ETIME - 1/86400
GROUP BY cll.SUBS_ID, bs.REG_ID, bs.REGION, zttc.COMM_NAME, zttt.TRAFIK_NAME, ztt.TRPL_NAME)
Where KOLVO1 >= 20 Or KOLVO2 >= 500 Or KOLVO3 >= 100 Or KOLVO4 >= 1000)
)
...
Рейтинг: 0 / 0
Запрос по нескольким условиям GROUP BY HAVING
    #39948023
alex-ls
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а почему общий WITH не напишите для начала?
...
Рейтинг: 0 / 0
Запрос по нескольким условиям GROUP BY HAVING
    #39948044
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex-ls
а почему общий WITH не напишите для начала?

сложно учесть нюасы (граничные условия)

.....
stax
...
Рейтинг: 0 / 0
Запрос по нескольким условиям GROUP BY HAVING
    #39948089
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax

сложно учесть нюасы (граничные условия)


Да вроде не так и сложно:


Код: 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.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
WITH T1 AS (
            SELECT  bs.REG_ID AS REG_ID,
                    bs.REGION AS REGION,
                    zttc.COMM_NAME AS COMM_NAME,
                    zttt.TRAFIK_NAME AS TRAFIK_NAME,
                    ztt.TRPL_NAME AS TRPL_NAME,
                    cll.SUBS_ID AS SUBS_ID,
                    CASE
                      WHEN zttt.TRAF NOT IN (3, 5) AND cll.SERV_ID <> 166 THEN 'GRP1'
                      WHEN zttt.TRAF = 5 AND cll.SERV_ID = 166 THEN 'GRP2'
                      WHEN zttt.TRAF = 3 AND cll.SERV_ID <> 166 THEN 'GRP3'
                      WHEN zttt.TRAF = 3 AND cll.SERV_ID = 166 THEN 'GRP4'
                    END GRP
              FROM  SUBS_HISTORY sh,
                    Z_TARIFF_TYPE ztt,
                    Z_TARIFF_TYPE_COMM zttc,
                    Z_TARIFF_TYPE_TRAFIK zttt,
                    BASE_STATIONS bs,
                    CALL_D_03_2020 clld,
                    CALL_03_2020 cll
              WHERE cll.OWNER_CALL_ID = 0
                AND sh.SUBS_ID = cll.SUBS_ID
                AND cll.CALL_ID = clld.CALL_ID
                AND clld.CELL_A = bs.CELL_ID
                AND ztt.TRPL_ID = sh.TRPL_ID
                AND ztt.COMM = zttc.COMM
                AND ztt.TRAF = zttt.TRAF
                AND (
                        (
                               zttt.TRAF NOT IN (3, 5)
                         AND
                               cll.SERV_ID <> 166
                        )
                     OR (
                               zttt.TRAF = 5
                          AND 
                               cll.SERV_ID = 166
                        )
                     OR (
                             zttt.TRAF = 3
                         AND
                             cll.SERV_ID <> 166
                        )
                     OR (
                             zttt.TRAF = 3
                         AND
                             cll.SERV_ID = 166
                        )
                    )
                AND cll.START_TIME BETWEEN sh.STIME AND sh.ETIME - 1/86400
           ),
     T2 AS (
            SELECT  REG_ID,
                    REGION,
                    COMM_NAME,
                    TRAFIK_NAME,
                    TRPL_NAME,
                    SUBS_ID,
                    COUNT(cll.CALL_ID) AS KOLVO
              FROM  T1
              GROUP BY SUBS_ID,
                       REG_ID,
                       REGION,
                       COMM_NAME,
                       TRAFIK_NAME,
                       TRPL_NAME,
                       GRP
              HAVING COUNT(CALL_ID) >= CASE GRP
                                         WHEN 'GRP1' THEN 20
                                         WHEN 'GRP2' THEN 500
                                         WHEN 'GRP3' THEN 100
                                         ELSE 1000
                                       END
           )
SELECT  REG_ID,
        REGION,
        COMM_NAME,
        TRAFIK_NAME,
        TRPL_NAME,
        SUBS_ID,
        COUNT(UNIQUE SUBS_ID) AS KOLVO
  FROM  T2
  GROUP BY REG_ID,
           REGION,
           COMM_NAME,
           TRAFIK_NAME,
           TRPL_NAME
  ORDER BY REG_ID,
           COMM_NAME,
           TRPL_NAME
/




Но может быть обратный эффект с производительностью из-за OR.

SY.
...
Рейтинг: 0 / 0
Запрос по нескольким условиям GROUP BY HAVING
    #39948100
Alexander Warlord
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем большое спасибо! Первый вариант запроса самое то!
...
Рейтинг: 0 / 0
Запрос по нескольким условиям GROUP BY HAVING
    #39948109
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY
Stax

сложно учесть нюасы (граничные условия)


Да вроде не так и сложно:

SY.

я имел ввиду тестовые данные

зы

если условия

1. TRAF NOT IN (3, 5)
SERV_ID <> 166

2. TRAF NOT IN (3, 5)
SERV_ID = 166

3. TRAF NOT = 3
SERV_ID <> 166

4. TRAF NOT = 3
SERV_ID = 166


не пересекаются (а они вроде не пересекаются) то or заменит union all

.....
stax
...
Рейтинг: 0 / 0
Запрос по нескольким условиям GROUP BY HAVING
    #39948123
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Запрос по нескольким условиям GROUP BY HAVING
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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