【发布时间】:2015-05-30 14:59:23
【问题描述】:
我有我无法弄清楚的 SQL (MySQL)。该应用程序正在使用上传的照片,其中一张照片中有许多被标记的参与者,并且有可能在 1 到 5 之间给照片投票。
原始查询获取一张照片的所有投票,并按投票数量和投票的平均值对它们进行排序。
现在我需要限制超过 1 个参与者返回的照片。因此,不应考虑只有 1 位参与者的照片。
简化的架构如下所示。
PHOTOS
----------------------
| id | title |
----------------------
| 1 | Fun stuff |
| 2 | Crazy girls |
| 3 | Single boy |
PHOTO_VOTES
-------------------------------------------
| photo_id | grade | date | user_id |
-------------------------------------------
| 1 | 3 | … | 12 |
| 1 | 3 | … | 12 |
| 2 | 5 | … | 14 |
| 2 | 4 | … | 14 |
| 3 | 4 | … | 15 |
| 3 | 4 | … | 18 |
PHOTO_PARTICIPANTS
-------------------------
| photo_id | user_id |
-------------------------
| 1 | 12 |
| 1 | 21 |
| 1 | 33 |
| 2 | 14 |
| 2 | 33 |
| 3 | 12 |
这是我走了多远:
SELECT vote.photo_id,
COUNT(vote.photo_id) AS vote_count,
AVG(vote.grade) AS vote_average,
COUNT(pp.photo_id) AS participant_count
FROM photo_votes vote
LEFT JOIN photos p ON (vote.photo_id = p.id)
LEFT JOIN photo_participants pp ON (pp.photo_id = p.id)
GROUP BY vote.post_id,
HAVING vote_count >= 2
AND vote_average >= 3
AND participant_count > 1
ORDER BY count DESC, average DESC;
基本上是我想要的结果,不包括只有一位参与者的照片:
VOTES
-----------------------------------------------------------
| photo_id | vote_count | average | participant_count
-----------------------------------------------------------
| 1 | 2 | 3 | 3
| 2 | 2 | 4.5 | 2
更新
事实证明,这是一种非常低效的尝试做我想做的事情的方式。 Gordons 下面的回答确实解决了这个问题,但是当我也想加入照片表中的字段时,“笛卡尔积”问题就变成了一个真正的问题——它变成了一个非常繁重和缓慢的查询。
我最终得到的解决方案是在照片表中添加一个缓存字段,以跟踪照片中有多少参与者。换句话说,我在“照片”中添加了一个“participant_count”字段,每次对参与者表进行更改时都会更新该字段。我还定期运行 cron-job 以确保所有照片 'participant_count' 都是最新的。
【问题讨论】:
-
您的查询有什么问题?
标签: mysql