计算MySQL中特定行的平均值

时间:2014-11-29 17:44:47

标签: php mysql average greatest-n-per-group

我有以下两个表:

content:

| id | name  | created_by |
+----+-------+------------+
| 1  | test  |     me     |
| 2  | test2 |     me     |
| 3  | test3 |     you    |
| 4  | test4 |     me     |

like_dislike:

| id | content_id | like | dislike |
+----+------------+------+---------+
| 1  |     1      |  1   |    0    |
| 2  |     2      |  1   |    0    |
| 3  |     2      |  0   |    0    |

我需要计算created_by = me的最后2个内容行的平均值。

例如,最后两个content_id是2和4。

like_dislike表有content_id 2的记录,其中一行是like,一行是like,所以平均值是1/2。

我已尝试过以下查询但不起作用:

SELECT ((SELECT COUNT(*) 
   FROM `like_dislike` 
   WHERE `like`='1' AND `content_id`= pi.id) / (COUNT(*))
FROM content AS pi 
WHERE pi.create_by = 'me' 
ORDER BY pi.id DESC
LIMIT 2

3 个答案:

答案 0 :(得分:1)

SELECT x.* 
     , AVG(liked) 
  FROM content x 
  JOIN content y
    ON y.created_by = x.created_by 
   AND y.id >= x.id 
  JOIN like_dislike z
    ON z.content_id = x.id
 WHERE x.created_by = 'me' 
 GROUP BY x.id 
HAVING COUNT(DISTINCT y.id) <= 2;

或类似的东西

答案 1 :(得分:0)

看起来你在这里尝试做的事情,即使你可能没有看到它,也会获得最大的每组人数。有关详细信息,请参阅此article

那么,我要做的是先获取由您创建的最新两个content行,如下所示:

SELECT c.*
FROM content c
WHERE(
  SELECT COUNT(*)
  FROM content co
  WHERE co.created_by = c.created_by AND co.id >= c.id) <= 2
AND c.created_by = 'me';

接下来的部分我将逐渐走慢,因为它有点棘手。在content_id匹配的情况下,您可以使用like_dislike表加入上述内容,这样您就可以查看最近两篇帖子的总喜欢:

SELECT c.*, ld.*
FROM content c
JOIN like_dislike ld ON ld.content_id = c.id
WHERE(
  SELECT COUNT(*)
  FROM content co
  WHERE co.created_by = c.created_by AND co.id >= c.id) <= 2
AND c.created_by = 'me';

完成后,您可以使用AVG()功能获取平均喜欢,并按每个content_id进行分组,如下所示:

SELECT c.id, AVG(ld.liked) AS averageLikes
FROM content c
JOIN like_dislike ld ON ld.content_id = c.id
WHERE(
  SELECT COUNT(*)
  FROM content co
  WHERE co.created_by = c.created_by AND co.id >= c.id) <= 2
AND c.created_by = 'me'
GROUP BY c.id;

这里需要注意的一件重要事情:这只会显示与其相关的活动的帖子。换句话说,content_id 4将不会出现。如果你需要看到它,你可以进行LEFT JOIN,并检查平均值是否为null,如果是,则将其替换为0,如下所示:

SELECT c.id, IFNULL(AVG(ld.liked), 0) AS averageLikes
FROM content c
LEFT JOIN like_dislike ld ON ld.content_id = c.id
WHERE(
  SELECT COUNT(*)
  FROM content co
  WHERE co.created_by = c.created_by AND co.id >= c.id) <= 2
AND c.created_by = 'me'
GROUP BY c.id;

这是你的SQL Fiddle.

另请注意 like是MySQL中的保留字,因此我将小提琴中的两列更改为likeddisliked。我建议你这样做。

答案 2 :(得分:0)

如果您一次只想为一个用户提供此信息,那么您不需要使用自连接或变量进行奇特的操作。您可以在子查询中使用limit

select avg(like)
from like_dislike ld join
     (select c.*
      from content c
      where c.create_by = 'me'
      order by id
      limit 2
     ) c2
     on ld.content_id = c2.id;