我有父 posts
表和子 votes
与 posts.id
和 votes.post_id
关系。我想计算每个帖子的平均评分,但只计算最近给定的 50 票。我知道如何为所有选票做到这一点:
SELECT T1.`title`, (
SELECT AVG(`vote`)
FROM `votes`
WHERE `votes`.`post_id` = T1.`id`
) AS `average`
FROM `posts` T1
GROUP BY T1.`id`
我知道这可能与子查询有关:
SELECT T1.`title`, (
SELECT AVG(`vote`)
FROM (
SELECT `vote` FROM `votes`
WHERE `votes`.`post_id` = T1.`id`
ORDER BY `votes`.`id` DESC
LIMIT 10
) AS T2
) AS `average`
FROM `posts` T1
GROUP BY T1.`id`
但出现错误:查询错误 (1054):“where 子句”中的未知列“T1.id”
。 T1
别名在子子查询中不可访问。有什么想法吗?
最佳答案
好的,您想要选择每个帖子最近 50 行中的行。 Stack Overflow 上有很多针对此类查询的答案,大部分在 greatest-n-per-group 下。或 limit-per-group标签。示例:How to SELECT the newest four items per category?
一旦你编写了该查询,你就可以像你已经知道如何编写的那样放入一个子查询,以获得每个帖子的 AVG(vote)
。
回复你的评论:
这就是我的意思:
SELECT T1.title, AVG(V.vote) AS avg_vote
FROM posts T1
JOIN (
SELECT v1.id, v1.post_id, v1.vote
FROM votes v1
LEFT OUTER JOIN votes v2 ON v1.post_id = v2.post_id and v1.id < v2.id
GROUP BY v1.id
HAVING COUNT(*) < 10
) AS V ON T1.id = V.post_id
GROUP BY T1.id;
给定 SQLFiddle 中数据的输出:
+---------+----------+
| title | avg_vote |
+---------+----------+
| Title 1 | 5.4000 |
| Title 2 | 4.2000 |
+---------+----------+
为了帮助子查询中的 JOIN,您应该在列(post_id
、id
)上的 votes
上建立索引。
这是另一个不需要唯一列的解决方案:
SELECT T1.title, AVG(V.vote) AS avg_vote
FROM posts T1
JOIN (
SELECT *
FROM (
SELECT v.*, @r := IF(@p = post_id, @r+1, 1) AS rownum, @p := post_id
FROM (SELECT @p:=null, @r:=0) AS _init
CROSS JOIN votes v
ORDER BY v.post_id, v.id DESC
) AS t
WHERE t.rownum <= 10
) AS V ON T1.id = V.post_id
GROUP BY T1.id;
输出与之前的查询相同。
关于mysql - 每个有条件的 parent 的平均值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39583876/