Выполнять математические операции для вывода из COUNT и ГРУППИРОВАТЬ ПО statemetns

#sql #oracle #toad

#sql #Oracle #жаба

Вопрос:

Предположим, у меня есть столбец данных «Да» / «Нет». Затем я могу подсчитать наблюдения в каждой категории результатов по

 Select MyVar, count(MyVar) from MyTable
group by MyVaR;
  

Вывод выглядит примерно так:

 MyVar    count(MyVar)
Yes               10
No                5
  

Как я могу добавить еще один элемент в эту таблицу вывода, который является дробью (Да / Нет), чтобы моя итоговая таблица выглядела примерно так:

 MyVar    count(MyVar)
Yes               10
No                5
Fraction          2
  

Есть ли простое решение для этого?

Ответ №1:

Вы можете использовать group by grouping sets() для этого:

 Select 
   case 
      when grouping(MyVar)=0 then MyVar
      else 'Fraction'
   end grouping_value,
   case 
      when grouping(MyVar)=0 then count(MyVar) 
      else count(decode(MyVar,'Yes',1)) / count(decode(MyVar,'No',1))
   end c
from MyTable
group by grouping sets(MyVaR,())
  

Полный тестовый пример с образцами данных:

 with MyTable(MyVar) as (
  select * 
  from table(sys.odcivarchar2list(
               'Yes','Yes','Yes','Yes','Yes','Yes','Yes','Yes','Yes','Yes',
               'No','No','No','No','No'
            ))
)
Select 
   case 
      when grouping(MyVar)=0 then MyVar
      else 'Fraction'
   end grouping_value,
   case 
      when grouping(MyVar)=0 then count(MyVar) 
      else count(decode(MyVar,'Yes',1)) / count(decode(MyVar,'No',1))
   end val
from MyTable
group by grouping sets(MyVaR,())
;
  

Результаты:

 GROUPING_VALUE         VAL
--------------- ----------
No                       5
Yes                     10
Fraction                 2
  

Ответ №2:

Это проще всего — в этом формате — с помощью union all :

 with t as (
      Select MyVar, count(MyVar) as cnt
      from MyTable
      group by MyVaR
     )
select MyVar
from t
union all
select 'Ratio', sum(case when MyVar = 'Yes' then cnt else 0 end) / sum(case when MyVar = 'No' then cnt else 0 end)
from t;
  

Тем не менее, я бы просто использовал условную агрегацию и поместил все значения в одну строку:

 select sum(case when MyVar = 'Yes' then cnt else 0 end) as yes,
       sum(case when MyVar = 'Yes' then cnt else 0 end) as no,
       sum(case when MyVar = 'Yes' then cnt else 0 end) / sum(case when MyVar = 'No' then cnt else 0 end) as ratio
from t;