Oracle SQL — подсчет на основе условия включения отдельных строк с нулевыми совпадениями

#sql #oracle #count #analytic-functions

#sql #Oracle #подсчет #аналитические функции

Вопрос:

Есть ли «лучший» способ реорганизовать приведенный ниже запрос, который возвращает количество вхождений определенного значения (например 'A' ) для каждого отдельного id ? Проблема, похоже, сохраняется id = 2 в результирующем наборе, даже если счетчик равен нулю ( id = 2 никогда не связан с 'A' ). Он имеет общее табличное выражение, функцию NVL, встроенное представление, distinct и соединение по левому краю. Действительно ли все это необходимо для выполнения этой работы? (Oracle 19c)

 create table T (id, val) as
  select 1, 'A' from dual
  union all select 1, 'B' from dual
  union all select 1, 'A' from dual
  union all select 2, 'B' from dual
  union all select 2, 'B' from dual
  union all select 3, 'A' from dual
;

with C as (select id, val, count(*) cnt from T where val = 'A' group by id, val)
select D.id, nvl(C.cnt, 0) cnt_with_zero from (select distinct id from T) D left join C on D.id = C.id
order by id
;

        ID CNT_WITH_ZERO
---------- -------------
         1             2
         2             0
         3             1
 

Ответ №1:

Простой способ — это условная агрегация:

 select id,
       sum(case when val = 'A' then 1 else 0 end) as num_As
from t
group by id;
 

Если у вас есть другая таблица с одной строкой на идентификатор, я бы рекомендовал:

 select i.id,
       (select count(*) from t where t.id = i.id and t.val = 'A') as num_As
from ids i;