Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Упрощение запроса (группировка по условиям)  [new]
Alexander Warlord
Member

Откуда: Абхазия, Сухум
Сообщений: 296
Приветствую!

Возможно ли уменьшить данный запрос и избавиться от UNION'а?

SELECT
    TRUNC(s.ACTIVATION_DATE,'MM') AS ACTIVATION_DATE,
    'Офисы продаж' AS DEALER_NAME,
    COUNT(ph.MSISDN) AS KOLVO
FROM
    SUBS_HISTORY sh,
    TARIFF_PLAN tp,
    CONTRACT ct,
    DEALER dl,
    PHONE ph,
    SUBSCRIBER s
WHERE
    s.SUBS_ID = sh.SUBS_ID
    AND ph.PHONE_ID = sh.PHONE_ID
    AND sh.TRPL_ID = tp.TRPL_ID
    AND ct.CLNT_ID = sh.CLNT_ID
    AND ct.DLR_ID = dl.DLR_ID
    AND dl.DLR_ID IN (4,5,57,60,94,158,161,214,219,232,233,244,293,309,560,562,590,591)
    AND s.ACTIVATION_DATE IS NOT NULL
    AND s.ACTIVATION_DATE BETWEEN sh.STIME AND sh.ETIME - 1/86400
    AND s.ACTIVATION_DATE BETWEEN ct.STIME AND ct.ETIME - 1/86400
    AND s.ACTIVATION_DATE >= TRUNC(:DATE1)
    AND s.ACTIVATION_DATE <= TRUNC(:DATE2) + 1 - 1 / 86400
GROUP BY TRUNC(s.ACTIVATION_DATE,'MM')
UNION ALL
SELECT
    TRUNC(s.ACTIVATION_DATE,'MM') AS ACTIVATION_DATE,
    'Собственные дилеры' AS DEALER_NAME,
    COUNT(ph.MSISDN) AS KOLVO
FROM
    SUBS_HISTORY sh,
    TARIFF_PLAN tp,
    CONTRACT ct,
    DEALER dl,
    PHONE ph,
    SUBSCRIBER s
WHERE
    s.SUBS_ID = sh.SUBS_ID
    AND ph.PHONE_ID = sh.PHONE_ID
    AND sh.TRPL_ID = tp.TRPL_ID
    AND ct.CLNT_ID = sh.CLNT_ID
    AND ct.DLR_ID = dl.DLR_ID
    AND dl.DLR_ID IN (301,302)
    AND s.ACTIVATION_DATE IS NOT NULL
    AND s.ACTIVATION_DATE BETWEEN sh.STIME AND sh.ETIME - 1/86400
    AND s.ACTIVATION_DATE BETWEEN ct.STIME AND ct.ETIME - 1/86400
    AND s.ACTIVATION_DATE >= TRUNC(:DATE1)
    AND s.ACTIVATION_DATE <= TRUNC(:DATE2) + 1 - 1 / 86400
GROUP BY TRUNC(s.ACTIVATION_DATE,'MM')
UNION ALL
SELECT
    TRUNC(s.ACTIVATION_DATE,'MM') AS ACTIVATION_DATE,
    'Реализация на Псоу' AS DEALER_NAME,
    COUNT(ph.MSISDN) AS KOLVO
FROM
    SUBS_HISTORY sh,
    TARIFF_PLAN tp,
    CONTRACT ct,
    DEALER dl,
    PHONE ph,
    SUBSCRIBER s
WHERE
    s.SUBS_ID = sh.SUBS_ID
    AND ph.PHONE_ID = sh.PHONE_ID
    AND sh.TRPL_ID = tp.TRPL_ID
    AND ct.CLNT_ID = sh.CLNT_ID
    AND ct.DLR_ID = dl.DLR_ID
    AND dl.DLR_ID IN (561)
    AND s.ACTIVATION_DATE IS NOT NULL
    AND s.ACTIVATION_DATE BETWEEN sh.STIME AND sh.ETIME - 1/86400
    AND s.ACTIVATION_DATE BETWEEN ct.STIME AND ct.ETIME - 1/86400
    AND s.ACTIVATION_DATE >= TRUNC(:DATE1)
    AND s.ACTIVATION_DATE <= TRUNC(:DATE2) + 1 - 1 / 86400
GROUP BY TRUNC(s.ACTIVATION_DATE,'MM')
UNION ALL
SELECT
    TRUNC(s.ACTIVATION_DATE,'MM') AS ACTIVATION_DATE,
    'Департамент развития' AS DEALER_NAME,
    COUNT(ph.MSISDN) AS KOLVO
FROM
    SUBS_HISTORY sh,
    TARIFF_PLAN tp,
    CONTRACT ct,
    DEALER dl,
    PHONE ph,
    SUBSCRIBER s
WHERE
    s.SUBS_ID = sh.SUBS_ID
    AND ph.PHONE_ID = sh.PHONE_ID
    AND sh.TRPL_ID = tp.TRPL_ID
    AND ct.CLNT_ID = sh.CLNT_ID
    AND ct.DLR_ID = dl.DLR_ID
    AND (dl.DLR_ID IN (285,677)
    OR dl.DEP_DLR_ID = 285)
    AND s.ACTIVATION_DATE IS NOT NULL
    AND s.ACTIVATION_DATE BETWEEN sh.STIME AND sh.ETIME - 1/86400
    AND s.ACTIVATION_DATE BETWEEN ct.STIME AND ct.ETIME - 1/86400
    AND s.ACTIVATION_DATE >= TRUNC(:DATE1)
    AND s.ACTIVATION_DATE <= TRUNC(:DATE2) + 1 - 1 / 86400
GROUP BY TRUNC(s.ACTIVATION_DATE,'MM')
UNION ALL
SELECT
    TRUNC(s.ACTIVATION_DATE,'MM') AS ACTIVATION_DATE,
    'Дилеры' AS DEALER_NAME,
    COUNT(ph.MSISDN) AS KOLVO
FROM
    SUBS_HISTORY sh,
    TARIFF_PLAN tp,
    CONTRACT ct,
    DEALER dl,
    PHONE ph,
    SUBSCRIBER s
WHERE
    s.SUBS_ID = sh.SUBS_ID
    AND ph.PHONE_ID = sh.PHONE_ID
    AND sh.TRPL_ID = tp.TRPL_ID
    AND ct.CLNT_ID = sh.CLNT_ID
    AND ct.DLR_ID = dl.DLR_ID
    AND dl.DLR_ID NOT IN (4,5,57,60,94,158,161,214,219,232,233,244,293,309,560,562,590,591,
    301,302,561,285,677)
    AND (dl.DEP_DLR_ID NOT IN (285) or dl.DEP_DLR_ID IS NULL)
    AND s.ACTIVATION_DATE IS NOT NULL
    AND s.ACTIVATION_DATE BETWEEN sh.STIME AND sh.ETIME - 1/86400
    AND s.ACTIVATION_DATE BETWEEN ct.STIME AND ct.ETIME - 1/86400
    AND s.ACTIVATION_DATE >= TRUNC(:DATE1)
    AND s.ACTIVATION_DATE <= TRUNC(:DATE2) + 1 - 1 / 86400
GROUP BY TRUNC(s.ACTIVATION_DATE,'MM')


Пробовал CASE'ом, ругается на группировку..
13 сен 17, 12:49    [20792500]     Ответить | Цитировать Сообщить модератору
 Re: Упрощение запроса (группировка по условиям)  [new]
982183
Member

Откуда:
Сообщений: 787
Покажи как пробовал
13 сен 17, 13:11    [20792607]     Ответить | Цитировать Сообщить модератору
 Re: Упрощение запроса (группировка по условиям)  [new]
-2-
Member

Откуда:
Сообщений: 12963
Alexander Warlord
Пробовал CASE'ом, ругается на группировку..
group by CASE'ом по dl.DLR_ID IN (...) или сделай справочник и добавь джоин.
13 сен 17, 13:12    [20792610]     Ответить | Цитировать Сообщить модератору
 Re: Упрощение запроса (группировка по условиям)  [new]
Alexander Warlord
Member

Откуда: Абхазия, Сухум
Сообщений: 296
982183
Покажи как пробовал


Вот так:

SELECT
    TRUNC(s.ACTIVATION_DATE,'MM') AS ACTIVATION_DATE,
    (CASE
        WHEN dl.DLR_ID IN (4,5,57,60,94,158,161,214,219,232,233,244,293,309,560,562,590,591) THEN COUNT(ph.MSISDN) END) AS "Офисы продаж",
    (CASE WHEN dl.DLR_ID IN (301,302) THEN COUNT(ph.MSISDN) END) AS "Собственные дилеры"
FROM
    SUBS_HISTORY sh,
    TARIFF_PLAN tp,
    CONTRACT ct,
    DEALER dl,
    PHONE ph,
    SUBSCRIBER s
WHERE
    s.SUBS_ID = sh.SUBS_ID
    AND ph.PHONE_ID = sh.PHONE_ID
    AND sh.TRPL_ID = tp.TRPL_ID
    AND ct.CLNT_ID = sh.CLNT_ID
    AND ct.DLR_ID = dl.DLR_ID
    AND s.ACTIVATION_DATE IS NOT NULL
    AND s.ACTIVATION_DATE BETWEEN sh.STIME AND sh.ETIME - 1/86400
    AND s.ACTIVATION_DATE BETWEEN ct.STIME AND ct.ETIME - 1/86400
    AND s.ACTIVATION_DATE >= TRUNC(:DATE1)
    AND s.ACTIVATION_DATE <= TRUNC(:DATE2) + 1 - 1 / 86400
GROUP BY TRUNC(s.ACTIVATION_DATE,'MM')


ругается на ct.DLR_ID
13 сен 17, 15:49    [20793145]     Ответить | Цитировать Сообщить модератору
 Re: Упрощение запроса (группировка по условиям)  [new]
Alexander Warlord
Member

Откуда: Абхазия, Сухум
Сообщений: 296
-2-
Alexander Warlord
Пробовал CASE'ом, ругается на группировку..
group by CASE'ом по dl.DLR_ID IN (...) или сделай справочник и добавь джоин.

Попробую так..
13 сен 17, 15:49    [20793146]     Ответить | Цитировать Сообщить модератору
 Re: Упрощение запроса (группировка по условиям)  [new]
MaximaXXL
Member

Откуда: Киев
Сообщений: 304
Alexander Warlord,

Попробуй так:
SELECT
    TRUNC(s.ACTIVATION_DATE,'MM') AS ACTIVATION_DATE,
    CASE
       WHEN dl.DLR_ID IN (4,5,57,60,94,158,161,214,219,232,233,244,293,309,560,562,590,591) THEN 'Офисы продаж'
       WHEN dl.DLR_ID IN (301,302) Then 'Собственные дилеры'
--...........
END AS DEALER_NAME ,
    COUNT(ph.MSISDN) AS "Собственные дилеры"
FROM
    SUBS_HISTORY sh,
    TARIFF_PLAN tp,
    CONTRACT ct,
    DEALER dl,
    PHONE ph,
    SUBSCRIBER s
WHERE
    s.SUBS_ID = sh.SUBS_ID
    AND ph.PHONE_ID = sh.PHONE_ID
    AND sh.TRPL_ID = tp.TRPL_ID
    AND ct.CLNT_ID = sh.CLNT_ID
    AND ct.DLR_ID = dl.DLR_ID
    AND s.ACTIVATION_DATE IS NOT NULL
    AND s.ACTIVATION_DATE BETWEEN sh.STIME AND sh.ETIME - 1/86400
    AND s.ACTIVATION_DATE BETWEEN ct.STIME AND ct.ETIME - 1/86400
    AND s.ACTIVATION_DATE >= TRUNC(:DATE1)
    AND s.ACTIVATION_DATE <= TRUNC(:DATE2) + 1 - 1 / 86400
GROUP BY TRUNC(s.ACTIVATION_DATE,'MM'),
    CASE
       WHEN dl.DLR_ID IN (4,5,57,60,94,158,161,214,219,232,233,244,293,309,560,562,590,591) THEN 'Офисы продаж'
       WHEN dl.DLR_ID IN (301,302) Then 'Собственные дилеры'
--...........
END
13 сен 17, 16:38    [20793315]     Ответить | Цитировать Сообщить модератору
 Re: Упрощение запроса (группировка по условиям)  [new]
MaximaXXL
Member

Откуда: Киев
Сообщений: 304
Alexander Warlord,

Только следи, твои строки разбиты на условия по 2 полям dl.DLR_ID и dl.DEP_DLR_ID.
Если ты перепишешь на 1 селект, то в нем 1 строка считается 1 раз, а через UNION может считаться много раз

пример
with t as (select 4 DLR_ID, 285 DEP_DLR_ID from dual)

select count(*) from t where DLR_ID = 4
union all
select count(*) from t where DEP_DLR_ID = 285

count(*)
1
1
13 сен 17, 16:52    [20793360]     Ответить | Цитировать Сообщить модератору
 Re: Упрощение запроса (группировка по условиям)  [new]
Alexander Warlord
Member

Откуда: Абхазия, Сухум
Сообщений: 296
Это да, понимаю. Большое спасибо за помощь!)
13 сен 17, 17:16    [20793430]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить