我有3个表,一个存储图片,一个存储图片投票(pictures
和picture_votes
)。最后一个表是categories
,它存储图片可以属于的不同类别。
以下是表格(省略了非相关栏目);
- Table `pictures`
picture_id INT
category_id INT
和
- Table `picture_votes`
vote TINYINT
picture_id INT
最后
- Table `categories`
category_id INT
我想要做的是是为每个类别选择前3个最多投票的图片。
我真的迷路了,不知道如何最有效地做到这一点。
答案 0 :(得分:2)
如果您可以在每个类别的一行中接受它们作为逗号分隔列表:
select pv.category_id,
substring_index(group_concat(pv.picture_id order by numvotes desc), ',', 3) as Top3
from (select p.category_id, p.picture_id, count(*) as numvotes
from picture_votes pv join
pictures p
on p.picture_id = pv.picture_id
group by p.category_id, p.picture_id
) pv
group by pv.category_id;
答案 1 :(得分:0)
我想出了这个;
(SELECT p.*
FROM
pictures p
LEFT JOIN
picture_votes pv
ON pv.picture_id = p.picture_id
WHERE p.category_id = n
GROUP BY p.picture_id
ORDER BY SUM(pv.vote) DESC
LIMIT 3)
UNION
(SELECT ...)
UNION
(SELECT ...)
--And so on for every category_id (there are 9)
这看起来像是一个糟糕的解决方案,查询时间太长了。
答案 2 :(得分:0)
SELECT category_id,picture_id,ranking FROM
(
select c.category_id,(select p.picture_id
from pictures p, picture_votes pv
where p.picture_id = pv.picture_id
and p.category_id = c.category_id
group by p.picture_id
order by sum(pv.vote) desc
limit 0,1)as picture_id,1 as ranking
from categories c
union
select c.category_id,(select p.picture_id
from pictures p, picture_votes pv
where p.picture_id = pv.picture_id
and p.category_id = c.category_id
group by p.picture_id
order by sum(pv.vote) desc
limit 1,1)as picture_id,2 as ranking
from categories c
union
select c.category_id,(select p.picture_id
from pictures p, picture_votes pv
where p.picture_id = pv.picture_id
and p.category_id = c.category_id
group by p.picture_id
order by sum(pv.vote) desc
limit 2,1)as picture_id,3 as ranking
from categories c
)result
WHERE picture_id is not null
order by category_id asc,ranking asc
SELECT picture_id,category_id,sumvotes,voteOrder
FROM
(SELECT picture_id,category_id,sumvotes,
IF(@prevCat <> category_id,@voteOrder:=1,@voteOrder:=@voteOrder+1)
as voteOrder,
@prevCat:=category_id
FROM(SELECT p.picture_id,
p.category_id,
SUM(pv.vote) as sumvotes
FROM pictures p
JOIN picture_votes pv
ON p.picture_id = pv.picture_id
GROUP BY p.picture_id,
p.category_id
ORDER BY p.category_id, sumvotes DESC
)as ppv,
(SELECT @prevCat:=0,@voteOrder:=0)pc
)finalTable
WHERE voteOrder BETWEEN 1 AND 3
ORDER BY category_id ASC, voteOrder ASC