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

Есть запрос по нескольким 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
16.04.2020, 11:32
    #39947953
PuM256
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос по нескольким условиям GROUP BY HAVING
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
16.04.2020, 13:56
    #39948023
alex-ls
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос по нескольким условиям GROUP BY HAVING
а почему общий WITH не напишите для начала?
...
Рейтинг: 0 / 0
16.04.2020, 14:52
    #39948044
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос по нескольким условиям GROUP BY HAVING
alex-ls
а почему общий WITH не напишите для начала?

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

.....
stax
...
Рейтинг: 0 / 0
16.04.2020, 16:09
    #39948089
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос по нескольким условиям GROUP BY HAVING
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
16.04.2020, 16:39
    #39948100
Alexander Warlord
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос по нескольким условиям GROUP BY HAVING
Всем большое спасибо! Первый вариант запроса самое то!
...
Рейтинг: 0 / 0
16.04.2020, 16:52
    #39948109
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос по нескольким условиям GROUP BY HAVING
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
16.04.2020, 17:10
    #39948123
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос по нескольким условиям GROUP BY HAVING
.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Запрос по нескольким условиям GROUP BY HAVING / 8 сообщений из 8, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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