Агрегация в Oracle SQL

Мне нужна помощь с проблемой агрегации в Oracle SQL. Я надеюсь, что это не слишком просто, но я действительно не знаю, как это сделать.

У меня есть следующие столбцы:

Customer_ID  (int)
Countract_ID (int)
  • Каждый контракт может включать в себя несколько разных клиентов
  • Каждый клиент может быть включен в несколько договоров.

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

ContractID  |CustomerID | "AVG sum of contracs per member in the contract"
123         | 11        |(3 + 2 + 1) / 3 = 2
123         | 22        |(3 + 2 + 1) / 3 = 2
123         | 33        |(3 + 2 + 1) / 3 = 2
321         | 11        |(3 + 2 + 2 + 1)  / 4  = 2
321         | 55        |(3 + 2 + 2 + 1)  / 4  = 2
321         | 22        |(3 + 2 + 2 + 1)  / 4  = 2
321         | 88        |(3 + 2 + 2 + 1)  / 4  = 2
987         | 11        |(3 + 2  + 1 + 1) / 4 = 1.75
987         | 55        |(3 + 2  + 1 + 1) / 4 = 1.75
987         | 99        |(3 + 2  + 1 + 1) / 4 = 1.75
987         | 77        |(3 + 2  + 1 + 1) / 4 = 1.75

Кто-нибудь знает, что такое запрос для таких как агрегация?

1 ответ

Решение

Вот один из подходов, где мы используем несколько аналитических функций: count() over() а также avg() over(),

-- sample of data
with t1(Contractid ,Customerid) as(
  select 123 , 11 from dual union all
  select 123 , 22 from dual union all
  select 123 , 33  from dual union all
  select 321 , 11  from dual union all
  select 321 , 55  from dual union all
  select 321 , 22  from dual union all
  select 321 , 88  from dual union all
  select 987 , 11  from dual union all
  select 987 , 55  from dual union all
  select 987 , 99  from dual union all
  select 987 , 77  from dual
 )
 -- the query
 -- analytic functions cannot be nested, thus inline vew
 select contractid
      , customerid
      , avg(cnt) over(partition by contractid) as average
  from ( select contractid
              , customerid    
              , count(contractid) over(partition by customerid) cnt
           from t1 )
 order by contractid, customerid

Результат:

CONTRACTID CUSTOMERID    AVERAGE
---------- ---------- ----------
       123         11          2
       123         22          2
       123         33          2
       321         11          2
       321         22          2
       321         55          2
       321         88          2
       987         11       1.75
       987         55       1.75
       987         77       1.75
       987         99       1.75

11 rows selected

Sqlfiddle demo

Другие вопросы по тегам