2008-09-18 25 views
6

Tôi có bảng có điểm số trò chơi, cho phép nhiều hàng cho mỗi id tài khoản: scores (id, score, accountid). Tôi muốn có danh sách 10 id ghi bàn hàng đầu và điểm số của họ.Tìm nạp một hàng cho mỗi id tài khoản từ danh sách

Bạn có thể cung cấp câu lệnh sql để chọn 10 điểm cao nhất, nhưng chỉ một điểm cho mỗi id tài khoản?

Cảm ơn!

+0

chúng tôi đang làm bài tập về nhà của bạn? – paulwhit

+4

Bài tập về nhà hay không, câu hỏi là IMHO tốt, vì DISTINCT đơn giản sẽ không hoạt động và cần kết hợp nó với hàm tổng hợp - một vấn đề tôi cũng gặp phải vài lần và có giải pháp trên SO sẽ mang lại lợi ích cho tất cả chúng ta. –

Trả lời

2

Đầu tiên giới hạn lựa chọn thành điểm cao nhất cho mỗi id tài khoản. Sau đó, lấy mười điểm số hàng đầu.

SELECT TOP 10 AccountId, Score 
FROM Scores s1 
WHERE AccountId NOT IN 
    (SELECT AccountId s2 FROM Scores 
    WHERE s1.AccountId = s2.AccountId and s1.Score > s2.Score) 
ORDER BY Score DESC 
+0

Hóa ra điều này có vẻ tốt hơn vì nó chọn toàn bộ hàng. Truy vấn tối đa khác chỉ được tacked trên số điểm tối đa cho một hàng ngẫu nhiên cho mỗi accountid. – Kenzie

+0

Cố định: SELECT * TỪ điểm s1 ĐÂU AccountID NOT IN (SELECT AccountID TỪ điểm s2 ĐÂU s1.accountid = s2.accountid và s1.score Kenzie

+2

Chỉ còn lại tôi có với truy vấn này là tôi nhận được nhiều hơn một hàng trên mỗi tài khoản khi tài khoản đó có nhiều hơn một lần xuất hiện của điểm số cao nhất của nó. Vì vậy, nếu accoundid 6 có điểm số là 50, 75, 40, 75 thì truy vấn trả về cả hai hàng với số điểm là 75. – Kenzie

2

Hãy thử điều này:

select top 10 username, 
       max(score) 
from usertable 
group by username 
order by max(score) desc 
+1

Có phải 'top 10' mới không? Tôi không nhớ nhìn thấy nó trước đây? – zigdon

+0

phụ thuộc vào DBMS - nó là mới đối với SQL Server vào năm 2000 – Danimal

+0

Tôi nên có quy định mysql. Giới hạn đã làm các trick. Cảm ơn. – Kenzie

1

PostgreSQL có DISTINCT ON khoản, mà làm việc theo cách này:

SELECT DISTINCT ON (accountid) id, score, accountid 
FROM scoretable 
ORDER BY score DESC 
LIMIT 10; 

Tôi không nghĩ rằng đó là SQL tiêu chuẩn mặc dù, vì vậy hy vọng cơ sở dữ liệu khác để làm điều đó khác nhau.

4
select username, max(score) from usertable group by username order by max(score) desc limit 10; 
+0

điều này cần một "desc" theo thứ tự của – Magnar

+0

Cập nhật, cảm ơn. – zigdon

1
SELECT accountid, MAX(score) as top_score 
FROM Scores 
GROUP BY accountid, 
ORDER BY top_score DESC 
LIMIT 0, 10

Điều đó sẽ làm việc tốt trong mysql. Có thể bạn có thể cần phải sử dụng 'ORDER BY MAX (điểm) DESC' thay vì thứ tự đó bởi - Tôi không có tham chiếu SQL của tôi trên tay.

0

Tôi tin rằng PostgreSQL (ít nhất 8.3) sẽ yêu cầu biểu thức DISTINCT ON phải khớp với biểu thức ORDER BY ban đầu. I E. bạn không thể sử dụng DISTINCT ON (accountid) khi bạn có ORDER BY score DESC. Để khắc phục điều này, hãy thêm nó vào trong ORDER BY:

SELECT DISTINCT ON (accountid) * 
FROM scoretable 
ORDER BY accountid, score DESC 
LIMIT 10; 

Sử dụng phương pháp này cho phép bạn chọn tất cả các cột trong bảng. Nó sẽ chỉ trả về 1 hàng trên mỗi tài khoản ngay cả khi có giá trị 'tối đa' trùng lặp cho điểm số.

Điều này rất hữu ích đối với tôi, vì tôi không tìm được số điểm tối đa (rất dễ làm với hàm max()) nhưng trong thời gian gần đây nhất điểm được nhập cho một tài khoản.

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