2009-04-29 16 views
6

私は、ある値がある列に現れる平均回数を調べ、別の列に基づいてそれをグループ化し、その上で計算を実行しようとしています。SQL AVG(COUNT(*))?

私は基本的に、私はローンのテーブルに平均回数よりも少ない回数を表示されるすべてのコピーIDを見つけるために、少しこのような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のすべてのコピーについて。

上記の例では、DVD1のコピー5が3回、コピー2が2回、コピー1が1回となるため、そのDVDの平均は2です。そのDVDのコピーをすべてリストしたいローンテーブルにその番号よりも少ない数字が表示されます。私はもう少し理にかなって願っています

...

おかげ

これは、Oracleで動作するはず
+0

したがって、どの結果データセットを返す必要がありますか? DVDID = 1の場合は2、それ以外の場合は1を出力する必要がありますか? –

+1

...「値が列に表示される平均回数」というのは意味をなさないためです。表示される回数は、表示される回数です。 1つの値を平均することはできません。 –

+0

申し訳ありませんが、私は半分眠っています!私は、各DVDのコピーがLoanテーブルに表示される平均回数を見たいと思っていました。 –

答えて

2

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

私は最近、この 'with'構文を見てきました。この標準SQLですか、それともOracleにありますか? –

+0

これはANSI SQL標準の一部です –