2011-01-23 5 views
8

Tôi có một số loại yêu cầu không thể được :).SQL - Cung cấp cho tôi 3 lần truy cập cho mỗi loại chỉ

Tôi có bảng nơi một trong các cột có tên là type. Tôi muốn SELECT 3 bản ghi cho từng loại trong cột đó. Điều đó có thể không?

Cũng lưu ý rằng tôi đang sử dụng MySQL và Sphinx.

UPDATE: cấu trúc Bảng

id  title  type 
1  AAAA   string1 
2  CCCC   string2 
3  EEEE   string2 
4  DDDD   string2 
5  FFFF   string2 
6  BBBB   string2 
6  BBBB   string2 

Những gì tôi muốn MySQL của tôi để trở lại là (tối đa 3 hồ sơ đối với từng loại lệnh của tiêu đề):

id  title  type 
1  AAAA   string1 
6  BBBB   string2 
2  CCCC   string2 
4  DDDD   string2 
+3

Đầu tiên, hầu như không có gì là không thể. Thứ hai, tại sao không hiển thị cấu trúc bảng của bạn và những gì bạn đã cố gắng cho đến nay. – ircmaxell

Trả lời

12
select id, title, type 
from (select id, title, type, 
       @num := if(@group = type, @num + 1, 1) as row_number, 
       @group := type as dummy 
     from your_table 
     order by type, title) as x 
where row_number <= 3 

(! Sử dụng a different article trên cùng một trang web như Martin Wickman's answer)

+0

Rất rất đẹp! – xpepermint

+0

+1 cho đơn đặt hàng cố định theo số – RichardTheKiwi

0

Check-out this bài viết. Đưa ra:

+--------+------------+-------+ 
| type | variety | price | 
+--------+------------+-------+ 
| apple | gala  | 2.79 | 
| apple | fuji  | 0.24 | 
| apple | limbertwig | 2.87 | 
| orange | valencia | 3.59 | 
| orange | navel  | 9.36 | 
| pear | bradford | 6.05 | 
| pear | bartlett | 2.14 | 
| cherry | bing  | 2.55 | 
| cherry | chelan  | 6.33 | 
+--------+------------+-------+ 

Query:

select type, variety, price 
from fruits 
where (
    select count(*) from fruits as f 
    where f.type = fruits.type and f.price < fruits.price 
) <= 2; 
+0

Truy vấn này sẽ hiển thị các mối quan hệ, vì vậy nếu 4 loại trái cây có cùng mức giá, tất cả đều hiển thị (thay vì 3). Cũng không có cố gắng liên kết với câu hỏi. – RichardTheKiwi

+0

Nếu sáu giống táo chia sẻ cùng một mức giá thấp nhất, tất cả sáu giống sẽ được trả lại. Nhưng ví dụ của OP tôi nghĩ rằng id có lẽ là một định danh duy nhất (nếu, đó là, hai "6" s được tạo ra như là kết quả của một JOIN) và bạn có thể sử dụng cột id thay vì cột giá để có được một kết quả chính xác được bảo đảm. –

2

Khi bảng là lớn và bộ sưu tập là không thể đoán trước hơn, việc đánh số liên tiếp cần phải được sắp xếp theo kiểu trong truy vấn bên trong để các biến tác dụng phụ hoạt động.

select id, title, type 
from (select id, title, type, 
     @r := CASE WHEN @g = type THEN @r+1 ELSE 1 END r, 
     @g := type 
     from tbl 
     order by type, title) as x 
where row_number <= 3 
# order by type, title 

Một cách khác để làm điều này mà không sử dụng các biến hiệu ứng phụ, nếu không có hai bản ghi chính xác giống nhau (tiêu đề, loại, id), được đưa ra dưới đây. Điều này chỉ sử dụng SQL chuẩn ANSI SQL92. Nó có thể chậm hơn so với ở trên mặc dù.

select A.id, A.title, A.type 
from tbl A 
left join tbl B on 
    A.title = B.title and 
    (A.type < B.type or 
    (A.type = B.type and A.id < A.id)) 
group by A.id, A.title, A.type 
having count(B.title) <= 2 
+0

Đúng, tôi phát hiện ra và sửa lỗi đó trước khi bài đăng này được đăng. –

2

Nếu bạn có một chỉ mục trên (type, title), và bạn biết các giá trị có thể cho type, tôi tin rằng SQL động là con đường để đi (cho một lần) cho hiệu suất tốt nhất.

Đối với mỗi giá trị có thể có của type, hãy thêm công đoàn và chọn cho loại cụ thể đó. Các truy vấn cuối cùng sẽ trông giống như truy vấn sau đây:

(select * from t1 where type = 'string1' order by title limit 3) 
    union all 
(select * from t1 where type = 'string2' order by title limit 3) 
    union all 
(select * from t1 where type = 'string3' order by title limit 3); 

Nó thực hiện trong vòng chưa đầy 1 giây trên một bảng với 1.000.000 hàng, trong khi các giải pháp khác (Martins & Cyberkiwis) mất khoảng 11 giây.

Sự khác biệt là vì truy vấn được kết hợp ở trên có thể tìm nạp ba tiêu đề đầu tiên cho mỗi loại và sau đó dừng, trong khi chức năng phân tích mô phỏng phải quét toàn bộ bảng.

+0

Cơ sở dữ liệu của tôi có 200 nghìn bản ghi và có hơn 500 loại. Bạn có đề nghị gì? – xpepermint

+0

@xpepermint, đi với giải pháp Martins. Chỉ cần biết rằng nó sẽ trở nên chậm hơn khi bạn thêm các bản ghi. Tại một số điểm, nó sẽ trở nên nhanh hơn để thực hiện 500 truy vấn trong một vòng lặp. Tùy thuộc vào thiết lập của bạn, điều này có thể đã xảy ra. Bạn phải tự đo mình. – Ronnis