2009-07-20 34 views
5

Tôi muốn giới hạn kích thước của các bản ghi bên trong một nhóm, và đây là bản dùng thử của tôi, làm thế nào để làm đúng?giới hạn mysql bên trong nhóm?

mysql> select * from accounts limit 5 group by type; 

ERROR 1064 (42000): Bạn có một lỗi trong cú pháp SQL của bạn; kiểm tra hướng dẫn tương ứng với phiên bản máy chủ MySQL của bạn cho đúng cú pháp để sử dụng gần 'nhóm theo loại' tại dòng 1

+0

Tôi nghĩ rằng những gì bạn muốn là một 'thứ tự', không phải là một' nhóm'. Bạn muốn liệt kê tối đa 5 của từng loại tài khoản, phải không? – Plutor

+0

vâng, làm thế nào để đạt được điều đó? – omg

+2

Chỉ cần By The Way, bạn phải đặt Giới hạn ở cuối '' của truy vấn. –

Trả lời

0

Đoàn tự do được sử dụng cho các chức năng tổng hợp (tiền, trung bình ...)

Cho phép bạn chia kết quả tổng hợp thành các nhóm. Bạn chưa sử dụng một trong các chức năng này.

0

Tôi không chắc chắn bạn có thể sử dụng giới hạn trong nhóm theo. Bạn có thể sử dụng nó nếu nhóm của bạn bằng một lựa chọn phụ trả về một hàng/giá trị. Ví dụ:

select * from trật tự foo bởi (chọn foo2.id từ giới hạn foo2 1)

Tôi chỉ đoán này sẽ làm việc.

1

Thử đặt mệnh đề LIMIT sau mệnh đề GROUP BY.

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

SELECT * 
FROM accounts a1 
WHERE 5 > 
(
    SELECT COUNT(*) 
    FROM accounts a2 
    WHERE a2.type = a1.type 
    AND a2.balance > a1.balance 
) 

này trả tối đa là 5 tài khoản của từng loại với số dư lớn nhất.

+0

đó không phải là những gì tôi muốn ... – omg

1

Dường như bạn muốn giới hạn số lượng hàng được trả lại trong mỗi nhóm trong tập hợp kết quả tổng thể của bạn ... điều này rất khó thực hiện theo cách có quy mô tốt. Một kỹ thuật là thực hiện N tham gia trên cùng một bảng với các điều kiện sao cho các hàng duy nhất khớp với nhau là N trên cùng/dưới cùng mà bạn muốn.

this page có thể cung cấp một số thông tin chi tiết bổ sung về giải pháp của bạn ... mặc dù trả lại 5 mục hàng đầu trong mỗi nhóm sẽ nhanh chóng trở nên xấu xí.

0

Điều này có thể sẽ thực hiện thủ thuật, mặc dù nếu type không được lập chỉ mục, nó sẽ là sloooowwww. Và ngay cả với một, nó không phải là đặc biệt nhanh:

SELECT a.* 
FROM accounts a 
    LEFT JOIN accounts a2 ON (a2.type = a.type AND a2.id < a.id) 
WHERE count(a2.id) < 5 
GROUP BY a.id; 

Một cược tốt hơn sẽ được chỉ order danh sách bởi type và sau đó sử dụng một vòng lặp tại các lớp kinh doanh để loại bỏ các hàng bạn không muốn.

5

Điểm của hàm tổng hợp (và GROUP BY nó yêu cầu) là chuyển nhiều hàng thành một hàng. Vì vậy, nếu bạn thực sự chỉ muốn 5 tài khoản tiết kiệm hàng đầu và 5 tài khoản tiết kiệm hàng đầu và 5 tài khoản USD hàng đầu, vv, bạn cần thêm như sau:

tiêu chí: top 5 loại tài khoản cụ thể bởi account_balance

SELECT account_type, account_balance FROM accounts WHERE account_type='savings' 
    ORDER BY account_balance DESC LIMIT 5 
UNION 
SELECT account_type, account_balance FROM accounts WHERE account_type='chequing' 
    ORDER BY account_balance DESC LIMIT 5 
UNION 
SELECT account_type, account_balance FROM accounts WHERE account_type='USD' 
    ORDER BY account_balance DESC LIMIT 5; 

Nó không đẹp, nhưng nếu bạn xây dựng SQL với một tập lệnh thì hãy thêm vào trong các account_types và nối với nhau một truy vấn rất đơn giản.

5

Tôi đã có một số may mắn với việc sử dụng hàng số:

set @type = ''; 
set @num = 0; 

select 
    items.*, 
    @num := if(@type = item_type, @num + 1, 1) as dummy_1, 
    @type := item_type as dummy_2, 
    @num as row_number 
from items 
group by 
    item_type, 
    row_number 
having row_number < 3; 

này sẽ cung cấp cho bạn 2 kết quả mỗi item_type. (Một Gotcha: đảm bảo bạn chạy lại hai set báo cáo đầu tiên bằng cách khác số hàng của bạn sẽ dần có được ngày càng cao và hạn chế row_number < 3 sẽ không làm việc

Tôi chắp này với nhau từ a coupleof posts đã được liên kết trong. other answers trên SO.

+1

Đây là câu trả lời hay nhất. Một điều bạn có thể làm là sử dụng một cái gì đó như thế này: 'từ mục, (SELECT @ type: = '', @num: = 0) v' và sau đó bạn có thể đặt các biến bên trong tham gia, thay vì trong một câu lệnh riêng biệt . Điều đó có thể hữu ích trong các môi trường không cho phép nhiều câu lệnh. –

0

@ câu trả lời dnagirl và gần như đã có nó, nhưng đối với một số lý do, phiên bản của tôi về MySQL chỉ trả về các thiết lập LIMIT'd đầu tiên. để khắc phục điều đó, tôi đưa từng tuyên bố vào một subquery

SELECT * FROM (
    SELECT account_type, account_balance FROM accounts WHERE account_type='savings' 
     ORDER BY account_balance DESC LIMIT 5 
) as a 
UNION 
SELECT* FROM (
    SELECT account_type, account_balance FROM accounts WHERE account_type='chequing' 
     ORDER BY account_balance DESC LIMIT 5 
) as b 
UNION 
SELECT * FROM (
    SELECT account_type, account_balance FROM accounts WHERE account_type='USD' 
     ORDER BY account_balance DESC LIMIT 5 
) as c 

Điều này đã cho m e quay lại kết quả của mỗi bộ trong tập kết quả cuối cùng. Nếu không, tôi sẽ chỉ nhận được 5 đầu tiên từ truy vấn đầu tiên và không có gì khác - không chắc chắn nếu nó chỉ là một số funk MySQL với phiên bản của tôi

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