как сделать множественный выбор с условной агрегацией - PullRequest
2 голосов
/ 23 сентября 2019

РЕДАКТИРОВАНИЕ Приведенный ниже запрос дает мне среднее значение всех типов покрытия на 2019 год при определенных условиях (обратите внимание, что триплет: число, имя и покрытие составляют элемент при первом выборе, а сумма из тех, которые ниже 0, равнаисключено; мне нужно получить среднее значение цены этих отфильтрованных элементов для каждого года, сгруппированных по охвату)

 Select ROUND(AVG(Amount), 2) average_2019, coverage, count(*) from
   (SELECT number, name, SUM(price) Amount, coverage, count(*) FROM myTable
where (To_date("Activity Date", 'mm-dd-yyyy') between TO_DATE('01/01/2019','mm/dd/yyyy') and TO_DATE('01/01/2019','mm/dd/yyyy'))
group by number, name, coverage having SUM(price)>0)
group by coverage;

Я хочу также отобразить среднее значение для других лет, например, 2018 и 2019, но у меня нетнашел способ сделать это.

вывод дает 3 столбца:

покрытия |средний2019 |считать

но я хочу 5 столбцов, включая 2018 год:

покрытия |средний2019 |считать |средний2018 |count

Я пытался использовать 'case when' для фильтрации по году, но тогда я не смогу выбрать по тройкам (имя, номер, охват), и мне нужно их среднее значение.Есть ли способ сделать это?

Ответы [ 2 ]

0 голосов
/ 23 сентября 2019

Я создал такую ​​таблицу:

create table myTable (numero number
                      , name varchar2(50)
                      , price number
                      , coverage number
                      , activity_date date);

И вставил некоторые данные:

insert into myTable values (1, 'name1', 20, 50, to_date('02.10.2018','dd.mm.yyyy'));
insert into myTable values (2, 'name2', 10, 50, to_date('05.10.2018','dd.mm.yyyy'));
insert into myTable values (3, 'name3', 40, 50, to_date('02.10.2019','dd.mm.yyyy'));
insert into myTable values (4, 'name3', 60, 50, to_date('10.10.2019','dd.mm.yyyy'));

Это подзапрос:

SELECT numero
       , name
       , SUM(price) Amount
       , coverage
       , count(*) 
       , max(extract(year from activity_date)) year
FROM myTable
where (activity_date between TO_DATE('02.10.2018','dd.mm.yyyy') 
      and TO_DATE('20.10.2019','dd.mm.yyyy'))
group by numero
         , name
         , coverage having SUM(price) > 0;

И запрос с подзапросом:

SELECT coverage as coverages,
       round(avg(case when year = 2018 then Amount end), 2) average2018,
       count( case when year = 2018 then Amount end) count_2018,
       round(avg(case when year = 2019 then Amount end), 2) average2019,
       count( case when year = 2019 then Amount end) count_2019
FROM
(SELECT numero
        , name
        , SUM(price) Amount
        , coverage
        , count(*) 
        , max(extract(year from activity_date)) year
FROM myTable
where (activity_date between TO_DATE('02.10.2018','dd.mm.yyyy') 
      and TO_DATE('20.10.2019','dd.mm.yyyy'))
group by numero
         , name
         , coverage having SUM(price) > 0)
group by coverage;
0 голосов
/ 23 сентября 2019

Хммм.,,Включает ли year в подзапрос то, что вы хотите?

Select typeItem, count(*), 
       round(avg(case when year = 2018 then price end), 2) avg_2018,
       round(avg(case when year = 2019 then price end), 2) average_2019
from (select number, name, typeItem, year, sum(price) as Amount, count(*)  as cnt             
      from myTable
      where status = 'active' 
      group by number, name, typeItem, year
      having SUM(price) > 0
     ) t
group by typeItem;

Мне немного непонятно, что вы хотите, чтобы значение count() учитывалось во внешнем запросе, так что значение может быть не тем, что выхочу.

...