2009-04-29 4 views
6

Я пытаюсь узнать среднее число раз, когда значение появляется в столбце, группируйте его на основе другого столбца и затем выполняйте вычисления на нем.SQL AVG (COUNT (*))?

У меня есть 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 которые меньше, чем это число в таблице займов.

Я надеюсь, что делает немного больше смысла ...

Благодаря

+0

Итак, в вашем примере, какой набор данных результата должен быть возвращен? Должен ли он выводить 2 для DVDID = 1 и 1 для двух других? –

+1

... потому что высказывание «среднее число раз, когда значение появляется в столбце» не имеет никакого смысла. Количество раз, когда оно появляется, - это количество раз, когда оно появляется; вы не можете усреднить одно значение. –

+0

Прости, я полусон! Я имел в виду, что хочу найти среднее число раз, когда копии каждого DVD появятся в таблице Loan – 2009-04-29 00:23:25

ответ

2

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

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

select avg(howmanytimes) from dvd_count_view; 
2

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

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

Подобно 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; 
+0

Я видел этот синтаксис в последнее время. Является ли этот стандартный SQL или находится в Oracle? –

+0

Это часть стандарта ANSI SQL –