Tôi đồng ý với Strawberry về lược đồ. Chúng tôi có thể thảo luận về các ý tưởng để có hiệu suất tốt hơn và tất cả những điều đó. Nhưng đây là cách giải quyết vấn đề này của tôi sau một vài cuộc trò chuyện và thay đổi câu hỏi.
Lưu ý bên dưới các thay đổi dữ liệu để đối phó với các điều kiện ranh giới khác nhau, bao gồm sách không có hình ảnh trong bảng đó và ngắt kết nối. Tie-break có nghĩa là sử dụng max(upvotes)
. OP đã thay đổi câu hỏi một vài lần và thêm một cột mới vào bảng hình ảnh.
Hàng đợi đã sửa đổi trở thành trả về 1 hàng được thực hiện cho mỗi cuốn sách. Cào đó, luôn luôn 1 hàng trên mỗi cuốn sách ngay cả khi không có hình ảnh. Thông tin hình ảnh cần trả lại sẽ là thông tin có số phiếu ủng hộ tối đa.
Bảng sách
create table books
( id int primary key,
name varchar(1000),
releasedate date,
purchasecount int
) ENGINE=InnoDB;
insert into books values(1,"fool","1963-12-18",456);
insert into books values(2,"foo","1933-12-18",11);
insert into books values(3,"fooherty","1943-12-18",77);
insert into books values(4,"eoo","1953-12-18",678);
insert into books values(5,"fooe","1973-12-18",459);
insert into books values(6,"qoo","1983-12-18",500);
Thay đổi dữ liệu so với câu hỏi ban đầu.
Chủ yếu là upvotes
mới cột.
Bên dưới bao gồm một hàng ngắt kết nối được thêm vào.
create table images
( bookid int,
poster varchar(150) primary key,
bucketid int,
upvotes int -- a new column introduced by OP
) ENGINE=InnoDB;
insert into images values (1,"xxx",12,27);
insert into images values (5,"pqr",11,0);
insert into images values (5,"swt",11,100);
insert into images values (2,"yyy",77,65);
insert into images values (1,"qwe",111,69);
insert into images values (1,"blah_blah_tie_break",111,69);
insert into images values (3,"qwqqe",14,81);
insert into images values (1,"qqawe",8,45);
insert into images values (2,"z",81,79);
Hình ảnh hóa bảng gốc
Điều này chỉ để hỗ trợ hình dung một phần bên trong của truy vấn cuối cùng. Nó thể hiện gotcha cho các tình huống tie-break, do đó, rownum
Biến đổi. Biến đó được đặt lại thành 1 mỗi lần bookid
thay đổi nếu không nó sẽ tăng lên. Cuối cùng (truy vấn cuối cùng của chúng tôi), chúng tôi chỉ muốn rownum=1
sao cho tối đa 1 hàng được trả về cho mỗi cuốn sách (nếu có).
Truy vấn cuối cùng
select b.id,b.purchasecount,xDerivedImages2.poster,xDerivedImages2.bucketid
from books b
left join
( select i.bookid,i.poster,i.bucketid,i.upvotes,
@rn := if(@lastbookid = i.bookid, @rn + 1, 1) as rownum,
@lastbookid := i.bookid as dummy
from
( select bookid,max(upvotes) as maxup
from images
group by bookid
) xDerivedImages
join images i
on i.bookid=xDerivedImages.bookid and i.upvotes=xDerivedImages.maxup
cross join (select @rn:=0,@lastbookid:=-1) params
order by i.bookid
) xDerivedImages2
on xDerivedImages2.bookid=b.id and xDerivedImages2.rownum=1
order by b.purchasecount desc
limit 10
Kết quả
+----+---------------+---------------------+----------+
| id | purchasecount | poster | bucketid |
+----+---------------+---------------------+----------+
| 4 | 678 | NULL | NULL |
| 6 | 500 | NULL | NULL |
| 5 | 459 | swt | 11 |
| 1 | 456 | blah_blah_tie_break | 111 |
| 3 | 77 | qwqqe | 14 |
| 2 | 11 | z | 81 |
+----+---------------+---------------------+----------+
Tầm quan trọng của cross join
chỉ đơn thuần là giới thiệu và đặt giá trị bắt đầu cho 2 biến. Đó là tất cả.
Kết quả là mười cuốn sách hàng đầu theo thứ tự giảm dần của purchasecount
với thông tin từ images
nếu nó tồn tại (nếu không thì NULL
) cho hình ảnh được ủng hộ nhiều nhất. Hình ảnh được chọn tôn vinh các quy tắc ràng buộc và chọn quy tắc đầu tiên như đã đề cập ở trên trong phần Hình ảnh hóa với rownum
.
Lời kết
Tôi để nó cho OP để đưa vào where
thích hợp ở cuối vì dữ liệu mẫu được cung cấp không có tên sách hữu ích để tìm kiếm. Phần đó là tầm thường. Ồ, và hãy làm điều gì đó về lược đồ cho chiều rộng lớn của các khóa chính của bạn. Nhưng đó là chủ đề vào lúc này.