Съгласен съм с Strawberry относно схемата. Можем да обсъждаме идеи за по-добро представяне и всичко това. Но ето моето мнение как да разреша това след няколко чатове и промени на въпроса.
Отбележете по-долу промените в данните, за да се справите с различни гранични условия, които включват книги без изображения в тази таблица и тай-брейк. Тайбрейк означава използване на 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
променлива. Тази променлива се нулира на 1 всеки път, когато bookid
променя в противен случай се увеличава. В крайна сметка (последната ни заявка) искаме само 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 променливи. Това е всичко.
Резултатите са първите десет книги в низходящ ред на purchasecount
с информацията от images
ако съществува (в противен случай NULL
) за най-гласуваното изображение. Избраното изображение спазва правилата за тайбрек, избирайки първото, както е споменато по-горе в раздела Визуализация с rownum
.
Последни мисли
Оставям на OP да вклини подходящото where
клауза в края, тъй като дадените примерни данни нямаха полезно име на книга, по което да се търси. Тази част е тривиална. О, и направете нещо относно схемата за голямата ширина на вашите първични ключове. Но това не е по темата в момента.