Агрегатные функции для вычисления дохода за два периода

Я только начинаю изучение SQL и ещё не очень хорошо с ним разобрался. Хотелось бы узнать, есть ли способ одним запросом вывести две суммы за два разных периода? Мой запрос (будет ниже) выводит только пересекающиеся строки в таблицах, и я никак не могу понять, как мне вывеси всё. Пробовал и left join, и full outer join - ничего не помогает. Данные берутся из двух таблиц - Договор и продукт.

В договоре есть: номер договора (PK), код продукта, дата договора, сумма

В Продукте: код продукта (РК), наименование продукта, код типа продукта.

    SELECT P.PROD_ID AS "Код", 
           P.PROD_NAME   AS "Наименование продукта", 
           SUM(C.TOTAL)  AS "Показатель на 4 квартал 2020 года", 
           SUM(C2.TOTAL) AS "Показатель на 1 квартал 2021 года"
    FROM PRODUCT p
    LEFT JOIN CONTRACT c
    ON P.PROD_ID = C.PROD_ID
    LEFT JOIN CONTRACT c2
    ON P.PROD_ID = C2.PROD_ID
    WHERE C.CONT_DATE BETWEEN TO_DATE('2020-10-01', 'YYYY-MM-DD') AND TO_DATE('2020-12-31', 'YYYY-MM-DD')
    AND C2.CONT_DATE BETWEEN TO_DATE('2021-01-01', 'YYYY-MM-DD') AND TO_DATE('2021-03-31', 'YYYY-MM-DD')
    AND P.PRTYPE_ID = 1
    GROUP BY P.PROD_ID, P.PROD_NAME, C.TOTAL, C2.TOTAL;

У меня этот запрос выводит вот это:

Код |Наименование продукта                   |Показатель на 4 квартал 2020 года|Показатель на 1 квартал 2021 года|
----+-------------------------------------------------------+---------------------------------+-------------------+
3|Фьючерсный контракт на обыкновенные акции  | 120536.69| 69582.29|

а должно быть примерно вот так плюс ещё один показатель на квартал.

Код |Наименование продукта |Показатель на 4 квартал 2020 года|
----+--------------------------------------------------------+
1|Фьючерсный контракт на обыкновенные акции | 46530.56|
2|Фьючерсный контракт на обыкновенные акции | 55945.35|
3|Фьючерсный контракт на обыкновенные акции | 69582.29|
1|Фьючерсный контракт на обыкновенные акции | 62167|

Буду благодарен, если вы сможете подсказать мне.


Ответы (1 шт):

Автор решения: 0xdb

По всей видимости, стоит задача вывести сумму по двум периодам времени, в данном случае - кварталы. Надо просто транспонировать (повернуть) агрегированный результат.

Пример данных (на db<>fiddle):

create table products (id primary key, name) as
    select rownum, trim (column_value)
    from xmlTable ('"prod1","prod2","prod3"')
/
create table contracts (id primary key, prodid, startdate, total) as
    select rownum, mod (rownum, 3)+1, date'2021-01-01'+rownum-1, 100
    from dual connect by level<=180
/

Сам запрос (где Q - маска формата для номера квартала):

select name, coalesce ("'Q1'", 0) "Q1", coalesce ("'Q2'", 0) "Q2" 
from (
    select p.id, p.name, 'Q'||to_char (c.startdate, 'Q') quarter, sum (c.total) total
    from products p 
    join contracts c on c.prodid = p.id
    group by p.id, p.name, to_char (c.startdate, 'Q'))
pivot (sum (total) for quarter in ('Q1','Q2'))

Даст ожидаемый результат:

NAME             Q1         Q2
-------- ---------- ----------
prod2          3000       3000
prod3          3000       3000
prod1          3000       3000
→ Ссылка