每个 parent 条件的平均值
Average for each parent with condition
我有 parent posts
table 和 child votes
与 posts.id
和 votes.post_id
关系。我想计算每个 post 的平均评分,但只计算最近给定的 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`
但出现错误:Error in query (1054): Unknown column 'T1.id' in 'where clause'
。 T1
子查询中无法访问别名。有什么想法吗?
好的,您想要选择每个 post 最近 50 行中的行。 Stack Overflow 上有很多针对此类查询的答案,大部分在 greatest-n-per-group or limit-per-group tags. Example: How to SELECT the newest four items per category?
下
一旦你写了那个查询,你就可以像你已经知道如何写的那样放入一个子查询,以获得每个 post.
的 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;
输出与之前的查询相同。
我有 parent posts
table 和 child votes
与 posts.id
和 votes.post_id
关系。我想计算每个 post 的平均评分,但只计算最近给定的 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`
但出现错误:Error in query (1054): Unknown column 'T1.id' in 'where clause'
。 T1
子查询中无法访问别名。有什么想法吗?
好的,您想要选择每个 post 最近 50 行中的行。 Stack Overflow 上有很多针对此类查询的答案,大部分在 greatest-n-per-group or limit-per-group tags. Example: How to SELECT the newest four items per category?
下一旦你写了那个查询,你就可以像你已经知道如何写的那样放入一个子查询,以获得每个 post.
的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;
输出与之前的查询相同。