我同意草莓关于模式的看法。我们可以讨论提高性能的想法等等。但是,在经过几次聊天和对问题的更改后,这是我对如何解决此问题的看法。
请注意下面的数据更改以处理各种边界条件,其中包括该表中没有图像的书籍和抢七。使用max(upvotes)
. OP 更改了几次问题并在图像表中添加了一个新列。
修改后的问题变为每本书返回 1 行。从头开始,即使没有图像,也总是每本书 1 行。要返回的图像信息将是获得最多支持的图像信息。
书桌
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);
原始问题的数据更改。
主要是新upvotes
栏目。
以下包括添加的抢七行。
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);
派生表的可视化
这只是为了帮助可视化最终查询的内部部分。它展示了抢七局的陷阱,因此也展示了rownum
变量。每次bookid
更改时,该变量都会重置为 1,否则会增加。最后(我们的最终查询)我们只需要rownum=1
行,以便每本书返回最多 1 行(如果有的话)。

最终查询
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
结果
+----+---------------+---------------------+----------+
| 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 |
+----+---------------+---------------------+----------+
的意义cross join
仅仅是引入和设置2个变量的起始值。就这些。
结果是按降序排列的前 10 本书,purchasecount
其中的信息来自images
是否存在(否则NULL
)对于最受好评的图像。所选择的图像尊重抢七规则,如上面在可视化部分中提到的第一个规则rownum
。
最后的想法
我把它留给 OP 在where
最后插入适当的子句,因为给出的示例数据没有有用的书名可供搜索。那部分是微不足道的。哦,对大宽度主键的模式做一些事情。但这目前是题外话。