Oracle: запрос, чтобы узнать, нет ли записи о цене для определенного квартала для продукта - PullRequest
1 голос
/ 21 октября 2019

У нас есть таблица цен, в которой есть столбцы продукт, квартал и цена. Данные выглядят следующим образом.

Product       Quarter  Price
    1         2019Q3   12.9
    1         2019Q1   5.9
    1         2018Q1   7.6
    2         2019Q2   2.2
    2         2019Q1   3.3

и т. Д. *

Мне нужно знать, для каких кварталов 2018 и 2019 годов у каждого продукта нет записей.

Таким образом, вывод должен быть таким:

 Product          Missing_Quarters

    1             2019Q4,2019Q2,2018Q4,2018Q3,2018Q2
    2             2019Q4,2019Q3,2018Q4,2018Q3,2018Q2,2018Q1

Ответы [ 2 ]

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

Это случай для внешнего многораздельного соединения , которое может "добавить" недостающий ключ (квартал) для каждого раздела (product_id)

Основной запрос, которыйсписок недостающих кварталов для каждого продукта выглядит следующим образом:

SELECT p.PRODUCT, q.QUARTER
FROM   PRICINGS p
PARTITION BY (p.Product)
RIGHT OUTER JOIN QUARTER q
ON p.Quarter = q.Quarter
where p.QUARTER is NULL
order by 1,2 ;

   PRODUCT QUARTE
---------- ------
         1 2018Q2
         1 2018Q3
         1 2018Q4
         1 2019Q2
         1 2019Q4
         2 2018Q1
         2 2018Q2
         2 2018Q3
         2 2018Q4
         2 2019Q3
         2 2019Q4

Остальное просто, как LISTAGG, используя порядок следования четвертей

with q as
(
SELECT p.PRODUCT, q.QUARTER
FROM   PRICINGS p
PARTITION BY (p.Product)
RIGHT OUTER JOIN QUARTER q
ON p.Quarter = q.Quarter
where p.QUARTER is NULL)
select PRODUCT,
listagg(QUARTER,',') within group (order by QUARTER DESC) qlist
from q
group by PRODUCT


PRODUCT, QLIST
1   2019Q4,2019Q2,2018Q4,2018Q3,2018Q2
2   2019Q4,2019Q3,2018Q4,2018Q3,2018Q2,2018Q1

Обратите внимание, что из соображений производительности этот способ предпочтительнее использования перекрестное соединение , поскольку вы выполняете оба соединения за один шаг.

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

Используйте cross join, чтобы сгенерировать все значения и затем отфильтровать те, которые существуют:

select p.product, 
       listagg(yq.yq, ',') within group (order by yq.yq) as quarters_missing
from (select '2018Q1' as yq from dual union all
      select '2018Q2' as yq from dual union all
      select '2018Q3' as yq from dual union all
      select '2018Q4' as yq from dual union all
      select '2019Q1' as yq from dual union all
      select '2019Q2' as yq from dual union all
      select '2019Q3' as yq from dual union all
      select '2019Q4' as yq from dual
     ) yq cross join
     (select distinct product from pricings) p left join      
     pricings pr
     on pr.product = p.product and pr.quarter = yq.yq
where pr.product is null
group by p.product;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...