我们正在创建一个包含以下表格的投票系统:
Color: id, name
Panel: id, name
Votes: id, color_id, panel_id
我们正在努力定义正确的查询以获得每个面板投票最多的颜色。
目前我们正在循环遍历所有面板(在Ruby中)并执行以下SQL查询:
select colors.name, count(colors.name) as count
from votes
join colors on colors.id = votes.renderable_id
where panel_id = X
group by colors.name
order by count desc
limit 1;
返回以下信息:
name | count
-----+-------
red | 34
我们希望通过对panel_id进行分组来优化并在查询中包含面板,这样我们就不需要遍历所有面板了。我们的第一次尝试就是:
select votes.panel_id, colors.name, count(colors.name) as count
from votes
join colors on colors.id = votes.renderable_id
group by votes.panel_id, colors.name;
返回
panel_id | name | count
---------+------+-------
8 | blue | 52
5 | blue | 14
8 | red | 34
我们还希望删除panel_id的重复项,并选择max(count)。我们不能让这个工作?
是否有SQL专家可以帮助我们将其实现为单个SQL查询?我们已经感谢您的努力。
答案 0 :(得分:0)
试试这个
select panel_id, max(count) as count
from (
select votes.panel_id, colors.name, count(colors.name) as count
from votes
join colors on colors.id = votes.renderable_id
group by votes.panel_id, colors.name
) src
group by panel_id
答案 1 :(得分:0)
如果您不需要面板和颜色名称,则只能使用一个表(这也是最快的解决方案):
SELECT panel_id, color_id, MAX(votes) FROM (
SELECT panel_id, color_id, COUNT(id) AS votes
FROM votes
GROUP BY panel_id, color_id;
) t1
如果你需要名字,那就非常相似:
SELECT panel_id, panel_name, color_id, color_name, MAX(votes) FROM (
SELECT panel_id, panel.name AS panel_name, color_id, color.name AS color_name, COUNT(id) AS votes
FROM votes
LEFT JOIN panel ON panel.id = votes.panel_id
LEFT JOIN color ON color.id = votes.color_id
GROUP BY panel_id, color_id;
) t1
答案 2 :(得分:0)
这是MySQL不支持的窗口函数的典型案例。因此,我们使用group_concat来列出按投票排序的每个面板的所有颜色,并删除第一个。
select best_votes.panel_id, colors.name, best_votes.maxcnt
from
(
select
panel_id,
max(cnt) as maxcnt,
substring_index(concat(group_concat(color_id order by cnt desc separator ','), ','), ',', 1) as maxcolor
from
(
select panel_id, color_id, count(*) as cnt
from votes
group by panel_id, color_id
)
group by panel_id
) best_votes
join colors on colors.id = best_votes.maxcolor;