SQL AVG (COUNT (*))? - PullRequest
       21

SQL AVG (COUNT (*))?

6 голосов
/ 29 апреля 2009

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

У меня есть 3 таблицы, примерно такие же

DVD

ID | NAME
1  | 1       
2  | 1     
3  | 2      
4  | 3

COPY 

ID | DVDID   
1  | 1  
2  | 1  
3  | 2  
4  | 3  
5  | 1

LOAN

ID | DVDID | COPYID  
1  | 1     |  1  
2  | 1     |  2  
3  | 2     |  3    
4  | 3     |  4  
5  | 1     |  5
6  | 1     |  5
7  | 1     |  5
8  | 1     |  2

и т.д.

По сути, я пытаюсь найти все идентификаторы копий, которые появляются в таблице ссуд, МЕНЬШЕ раз, чем среднее количество раз для всех копий этого DVD.

Таким образом, в приведенном выше примере копия 5 DVD-диска 1 появляется 3 раза, копия 2 дважды и копия 1 один раз, поэтому среднее значение для этого DVD равно 2. Я хочу перечислить все копии этого (и каждого другого) DVD, который в таблице ссуд меньше, чем это число.

Надеюсь, в этом есть смысл ...

Спасибо

Ответы [ 3 ]

2 голосов
/ 29 апреля 2009

Непроверено ...

with 
loan_copy_total as 
(
    select dvdid, copyid, count(*) as cnt
    from loan
    group by dvdid, copyid
),
loan_copy_avg as
(
    select dvdid, avg(cnt) as copy_avg
    from loan_copy_total
    group by dvdid
)

select lct.*, lca.copy_avg
from loan_copy_avg lca
inner join loan_copy_total lct on lca.dvdid = lct.dvdid
    and lct.cnt <= lca.copy_avg; 
2 голосов
/ 30 апреля 2009

Аналогично решению dotjoe, но с использованием аналитической функции, чтобы избежать дополнительного объединения. Может быть более или менее эффективным.

with 
loan_copy_total as 
(
    select dvdid, copyid, count(*) as cnt
    from loan
    group by dvdid, copyid
),
loan_copy_avg as
(
    select dvdid, copyid, cnt, avg(cnt) over (partition by dvdid) as copy_avg
    from loan_copy_total
)

select *
from loan_copy_avg lca
where cnt <= copy_avg;
2 голосов
/ 29 апреля 2009

Это должно работать в Oracle:

create view dvd_count_view
select dvdid, count(1) as howmanytimes
  from loans
 group by dvdid;

select avg(howmanytimes) from dvd_count_view;
...