Есть ли способ получить тот же вывод без использования подходов «JOINS» и «WITH AS»? - PullRequest
0 голосов
/ 05 октября 2019

У меня есть этот безумно длинный запрос, который дает мне среднюю группу по марке для каждого года, месяца и недели. Это прекрасно работает, но я слишком долго хочу знать, есть ли лучший способ сделать это и сохранить несколько строк кода. Я использую несколько «С как», потому что мне нужно отображать средние значения по неделям, месяцам, годам. Мне нужно среднее значение цены элементов, составленных триплетом id_item ||name_item ||марка, имеющая цену> = 1.

WITH 
YEAR_2018 AS(
SELECT BRAND, AVG(PRICE)AVG_2018, 0 AS AVG_2019, 0 AS JAN, 0 AS FEB...
FROM
(SELECT ID_ITEM || NAME_ITEM || BRAND, SUM(PRICE), BRAND, 
FROM MY TABLE
WHERE EXTRACT (YEAR FROM DATE) = 2018
GROUP BY ID_ITEM || NAME_ITEM || BRAND, BRAND)
GROUP BY BRAND)

YEAR_2019 AS(
SELECT BRAND, 0 AS AVG_2018, AVG(PRICE)AVG_2019, 0 AS JAN, 0 AS FEB...
FROM
(SELECT ID_ITEM || NAME_ITEM || BRAND, SUM(PRICE), BRAND, 
FROM MY TABLE
WHERE EXTRACT (YEAR FROM DATE) = 2019
GROUP BY ID_ITEM || NAME_ITEM || BRAND, BRAND)
GROUP BY BRAND)

JAN_2019 AS(...)
...

SELECT YEAR_2018.BRAND, YEAR_2018 .AVG_2018, YEAR_2019.AVG_2019 ...
FROM YEAR_2018 LEFT JOIN YEAR_2019 ON YEAR_2018.BRAND = YEAR_2019.BRAND
LEFT JOIN JAN_2019 ON JAN_2019.BRAND = YEAR_2018.BRAND ...
BRAND  |   AVG_2018  |  AVG_2019  |  AVG_JAN  |  AVG_FEB | ...
==============
X            13.2        ...
-----------------
Y            25.6        ...
-----------------

1 Ответ

1 голос
/ 05 октября 2019

Вы можете получить те же результаты с одним результатом, используя условное агрегирование:

SELECT 
    brand, 
    AVG(CASE WHEN EXTRACT(YEAR FROM my_date) = 2018 THEN price END) AVG_2018,
    AVG(CASE WHEN EXTRACT(YEAR FROM my_date) = 2019 THEN price END) AVG_2019,
    AVG(CASE WHEN TRUNC(my_date, 'mm') = TO_DATE('2018-01', 'yyyy-mm' THEN price END) THEN AVG_JAN_2018,
    AVG(CASE WHEN TRUNC(my_date, 'mm') = TO_DATE('2018-02', 'yyyy-mm' THEN price END) THEN AVG_FEB_2018,
    ....
FROM my_table
GROUP BY brand
WHERE EXTRACT(YEAR FROM my_date) IN (2018, 2019)

Этот метод использует тот факт, что AVG() игнорирует NULL значения.

...