2009-04-29 24 views
6

Tôi đang cố gắng tìm ra số lần trung bình một giá trị xuất hiện trong một cột, nhóm nó dựa trên một cột khác và sau đó thực hiện phép tính trên cột đó.SQL AVG (COUNT (*))?

Tôi có 3 bảng một chút như thế này

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 

vv

Về cơ bản, tôi đang cố gắng để tìm thấy tất cả các id bản sao xuất hiện trong bảng vay lần ít hơn số lần trung bình cho tất cả các bản sao của DVD đó. Vì vậy, trong ví dụ trên, sao chép 5 của dvd 1 xuất hiện 3 lần, sao chép 2 hai lần và sao chép 1 một lần để mức trung bình cho DVD đó là 2. Tôi muốn liệt kê tất cả các bản sao của (và DVD) khác xuất hiện ít hơn số đó trong bảng Loan.

Tôi hy vọng rằng có ý nghĩa nhiều hơn một chút ...

Cảm ơn

+0

Vì vậy, trong ví dụ của bạn, tập dữ liệu kết quả nào sẽ được trả lại? Nó có nên xuất ra 2 cho DVDID = 1 và 1 cho hai cái còn lại không? –

+1

... bởi vì nói 'số lần trung bình một giá trị xuất hiện trong một cột' không có ý nghĩa gì cả. Số lần nó xuất hiện là số lần nó xuất hiện; bạn không thể trung bình một giá trị. –

+0

Xin lỗi, tôi đang ngủ! Tôi có nghĩa là tôi muốn tìm số lần trung bình các bản sao của mỗi đĩa DVD xuất hiện trong bảng Loan –

Trả lời

2

này nên làm việc trong 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

chưa được kiểm tra ...

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

Tương tự như giải pháp của dotjoe, nhưng sử dụng một hàm phân tích để tránh sự tham gia thêm. Có thể hiệu quả hơn hoặc ít hơn.

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

Gần đây tôi đã nhìn thấy cú pháp 'với' này. Đây có phải là tiêu chuẩn SQL hay là nó trong Oracle? –

+0

Đó là một phần của tiêu chuẩn SQL ANSI –