2009-11-25 49 views
32

Khi tôi chạy câu lệnh SQL sau:SQL không phải là một chức năng nhóm đơn nhóm

SELECT MAX(SUM(TIME)) 
FROM downloads 
GROUP BY SSN 

Nó trả về giá trị tổng tối đa tải bởi khách hàng, tuy nhiên nếu tôi cố gắng tìm ra số an sinh xã hội mà giá trị tối đa thuộc về bằng cách thêm vào báo cáo kết quả chọn:

SELECT SSN, MAX(SUM(TIME)) 
FROM downloads 
GROUP BY SSN 

tôi nhận được lỗi sau:

not a single-group group function

Tôi không hiểu tại sao nó lại ném lỗi này. Một tìm kiếm google đã đưa ra các hành động sau đây:

Thả một trong hai chức năng nhóm hoặc biểu thức cột riêng lẻ từ danh sách SELECT hoặc thêm một mệnh đề GROUP BY bao gồm tất cả biểu thức cột cá nhân được liệt kê

Từ những gì tôi nghĩ rằng đây đang nói - việc giảm chức năng nhóm làm cho tổng giá trị không hợp lệ - thả biểu thức cột riêng lẻ (SSN) sẽ chỉ cho tôi số tiền tối đa - không chắc chắn về phần thứ ba đó.

Có ai có thể hướng dẫn đúng hướng không?

-Tomek

EDIT: TIME trong cơ sở dữ liệu này đề cập đến số lần tải về

Trả lời

34

Vâng vấn đề đơn giản-put là SUM (TIME) cho một SSN cụ thể về truy vấn của bạn là một đơn giá trị, do đó, nó phản đối MAX vì nó không có ý nghĩa (Tối đa của một giá trị đơn là vô nghĩa).

Không chắc máy chủ cơ sở dữ liệu SQL những gì bạn đang sử dụng nhưng tôi nghi ngờ bạn muốn truy vấn nhiều hơn như thế này (bằng văn bản với một nền MSSQL - có thể cần một số dịch đến máy chủ sql bạn đang sử dụng):

SELECT TOP 1 SSN, SUM(TIME) 
FROM downloads 
GROUP BY SSN 
ORDER BY 2 DESC 

Điều này sẽ cung cấp cho bạn số SSN có tổng thời gian cao nhất và tổng thời gian cho nó.

Edit - Nếu bạn có nhiều với thời gian như nhau và muốn họ tất cả các bạn sẽ sử dụng:

SELECT 
SSN, SUM(TIME) 
FROM downloads 
GROUP BY SSN 
HAVING SUM(TIME)=(SELECT MAX(SUM(TIME)) FROM downloads GROUP BY SSN)) 
+0

Tôi đang sử dụng oracle và không quen thuộc với việc nắm bắt các hàng cụ thể.Tuy nhiên điều gì sẽ xảy ra nếu có những khách hàng bị ràng buộc vì có số lượng tải xuống tối đa? – Tomek

+0

Nếu có nhiều số tiền với cùng số tiền, về cơ bản nó sẽ là ngẫu nhiên mà bạn nhận được (Có thể có một đơn đặt hàng ở mức thấp nhưng tôi không biết và cũng không dựa vào nó). Bạn có thể thêm các mệnh đề bổ sung vào thứ tự bằng cách nếu bạn muốn chỉ định cách tự mình đặt hàng. Nếu bạn muốn có được tất cả những cái được gắn trước, tôi tin rằng bạn sẽ cần các truy vấn lồng nhau, một để có được thời gian tối đa sau đó một lần nữa để kéo lại tất cả những cái đáp ứng nó (Cái gì đó như "SELECT SSN, SUM (TIME) FROM downloads NHÓM THEO S SSN SNN S SUMN (THỜI GIAN) = (CHỌN MAX (SUM (THỜI GIAN)) TỪ lượt tải TÊN NHÓM THEO SSN)) ") – fyjham

+0

PS: Không chắc chắn 100% có tồn tại trong Oracle không - ai đó có thể làm rõ điều đó. Hầu hết kinh nghiệm của tôi là TSQL. – fyjham

10

Nếu bạn muốn tải số cho mỗi khách hàng, sử dụng:

select ssn 
    , sum(time) 
    from downloads 
group by ssn 

Nếu bạn muốn chỉ một bản ghi - cho khách hàng có số lượt tải xuống cao nhất - sử dụng:

select * 
    from (
     select ssn 
      , sum(time) 
      from downloads 
     group by ssn 
     order by sum(time) desc 
     ) 
where rownum = 1 

Tuy nhiên nếu bạn wa nt để xem tất cả các khách hàng với cùng một số người tải về, mà chia sẻ vị trí cao nhất, sử dụng:

select * 
    from (
     select ssn 
      , sum(time) 
      , dense_rank() over (order by sum(time) desc) r 
      from downloads 
     group by ssn 
     ) 
where r = 1 
+0

Ví dụ thứ hai của bạn sẽ cung cấp cho khách hàng số lượng thấp nhất trừ khi đơn đặt hàng của bạn giảm dần – Khb

+0

Khb, bạn nói đúng. Tôi đã sửa nó. –

2

Có lẽ bạn tìm thấy điều này đơn giản hơn

select * from (
    select ssn, sum(time) from downloads 
    group by ssn 
    order by sum(time) desc 
) where rownum <= 10 --top 10 downloaders 

Trân
K

Các vấn đề liên quan