【问题标题】:Select most popular users given by likes, posts and comments通过喜欢、帖子和评论选择最受欢迎的用户
【发布时间】:2013-05-06 05:01:03
【问题描述】:

我有一个论坛,我想找到最受欢迎的用户。最受欢迎的用户由对帖子和 cmets 的最多点赞定义,也由最多的帖子和 cmets 定义。 点赞最多(顺序 1)、帖子最多(顺序 2)和 cmets 最多(顺序 3)的用户最受欢迎。同样的逻辑适用于下一个(第二个)最受欢迎的用户。

所以我有 3 张桌子:

帖子表

id      user_id     likes
1       1           0
2       1           0
3       1           0
4       1           0
5       1           0
6       1           1
7       1           0
8       2           0
9       2           2
10      2           0
11      2           0
12      3           0
13      3           0
14      4           0
15      4           10

cmets 表

id      user_id     likes
1       1           0
2       1           1
3       1           1
4       1           0
5       2           0
6       2           2
7       2           1
8       4           1
9       4           0

用户表

id      name
1       John
2       Adam
3       Maggie
4       Steve

“喜欢”列包含其他用户在相应帖子(行)上给予的喜欢。 我试过了:

 SELECT DISTINCT c.id, c.name,
    SUM(a.likes), SUM(b.likes), (SUM(a.likes) + SUM(b.likes)) as popular,
    COUNT(a.id) as mostp, COUNT(b.id) as mostc
    FROM posts as a, comments as b, users as c
    WHERE a.user_id=b.user_id AND a.user_id=c.id AND b.user_id=c.id
    GROUP BY a.user_id, b.user_id ORDER BY popular DESC, mostp DESC, mostc DESC

显然,这不起作用,因为如果您测试查询,它给出的点赞数(总和)比预期的要多。

这是实时查询 http://sqlfiddle.com/#!2/08900/3

【问题讨论】:

  • 将您的数据(或其子集)放入fiddle,以便我们这些无法访问 MySQL 的人为您提供帮助。
  • 你能发布你想要的输出吗
  • 所需的输出将是从 SUM 外推的结果与表中完全相同。错误的输出(就像现在一样)以笛卡尔积结束。

标签: mysql select


【解决方案1】:

您的查询的问题在于用户拥有多个帖子和多个评论,从而导致笛卡尔积并产生错误的总和。

下面的查询(SQL Fiddle 上的示例)应该可以工作,因为子查询已经按 user_id 分组:

SELECT
  u.name,
  COALESCE(p.likes,0) + COALESCE(c.likes,0) AS likes,
  COALESCE(p.cnt,0) AS post_count,
  COALESCE(c.cnt,0) AS comment_count
FROM users u
LEFT JOIN (
  SELECT user_id, COUNT(1) AS cnt, SUM(likes) AS likes
  FROM posts
  GROUP BY user_id
) p ON ( p.user_id = u.id )
LEFT JOIN (
  SELECT user_id, COUNT(1) AS cnt, SUM(likes) AS likes
  FROM comments
  GROUP BY user_id
) c ON ( c.user_id = u.id )
ORDER BY likes DESC, post_count DESC, comment_count DESC;

结果:

|   NAME | LIKES | POST_COUNT | COMMENT_COUNT |
-----------------------------------------------
|  Steve |    11 |          2 |             2 |
|   Adam |     5 |          4 |             3 |
|   John |     3 |          7 |             4 |
| Maggie |     0 |          2 |             0 |

【讨论】:

  • 像魅力一样工作!即使将新用户添加到用户表中,根本没有帖子或 cmets。再次感谢您提供有用的建议:)
【解决方案2】:

你可以这样做

SELECT
  u.id,
  u.name,
  (l.likes + r.likes) As TotalLikes,
  IFNULL(posts,0) AS TotalPosts,
  IFNULL(comments,0) AS TotalComments
FROM users AS u
  LEFT JOIN (SELECT
           user_id,
           IFNULL(SUM(likes),0) as likes,
           COUNT(likes) as posts
         FROM posts
         GROUP BY user_id) AS l
    on l.user_id = u.id
  LEFT JOIN (SELECT
           user_id,
           IFNULL(SUM(likes),0) as likes,
           COUNT(likes) AS comments
         FROM comments
         GROUP BY user_id) AS r
    on r.user_id = u.id
ORDER BY TotalLikes DESc

SQL Fiddle Demo

输出

| ID |   NAME | TOTALLIKES | TOTALPOSTS | TOTALCOMMENTS |
---------------------------------------------------------
|  4 |  Steve |         11 |          2 |             2 |
|  2 |   Adam |          5 |          4 |             3 |
|  1 |   John |          3 |          7 |             4 |
|  3 | Maggie |          0 |          2 |             0 |

【讨论】:

  • 您必须为l.liker.like 分别设置IFNULLs,否则只有cmets 帖子的用户将获得TotalLikes=0,即使他们有喜欢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-13
  • 2015-01-01
  • 1970-01-01
  • 2013-05-26
  • 1970-01-01
相关资源
最近更新 更多