SELECT user_id,
    SUM(COALESCE(point_points, 0)) AS total_points,
    SUM(
        CASE
            WHEN point_date > '$this_month'
            THEN point_points
            ELSE 0
        END)                AS month_points,
    COUNT(DISTINCT c_id)    AS num_comments,
    COUNT(DISTINCT rant_id) AS live_submissions
FROM users
    LEFT JOIN points
    ON  users.user_id = points.point_userid
    LEFT JOIN comments
    ON
        (
            c_userid = user_id
        )
    LEFT JOIN rants
    ON
        (
            rant_poster = user_id
        AND rant_status = 1
        )
WHERE user_id = $id
GROUP BY user_id

基本上live_submissionsnum_comments可变显示正确的结果,而total_pointsmonth_points显示month_points/total_pointslive_submissionsnum_comments的产物。任何想法,为什么发生这种情况?

有帮助吗?

解决方案

此被称为笛卡尔积。当您加入表一起,默认的结果是行的每一个排列作为其加入条件为真。您可以使用JOIN条件限制这些排列。

但是,因为要加入多个表以users,结果包括每个匹配表中的每个排列。例如,在points每个匹配行每行匹配重复comments,并且每个这些被再次相乘,每在rants匹配行重复。

您可以部分地为这个与COUNT(DISTINCT c_id)补偿,你在做什么,但DISTINCT是必要的,只是因为你必须每c_id多行。它不工作,除非你把它应用到独特的价值。这个补救措施没有为SUM()表达式工作。

基本上,你想在一个查询做太多的计算。您需要将它分割成单独的查询它是可靠的。然后你就可以摆脱DISTINCT改性剂,也。

SELECT u.user_id, SUM(COALESCE(p.point_points, 0)) AS total_points, 
  SUM( CASE WHEN p.point_date > '$this_month' THEN p.point_points ELSE 0 END ) AS month_points
FROM users u LEFT JOIN points p
  ON u.user_id = p.point_userid 
WHERE u.user_id = $id
GROUP BY u.user_id;

SELECT user_id, COUNT(c.c_id) as num_comments, 
FROM users u LEFT JOIN comments c
  ON (c.c_userid = u.user_id)
WHERE u.user_id = $id
GROUP BY u.user_id;

SELECT u.user_id, COUNT(r.rant_id) as live_submissions
FROM users u LEFT JOIN rants r
  ON (r.rant_poster = u.user_id AND r.rant_status = 1)
WHERE u.user_id = $id
GROUP BY u.user_id;

您不应该尝试做所有这三个在一个单一的查询。

其他提示

你能提供一些示例输出?

我认为这是与同分加咆哮和意见。你可以尝试删除咆哮和意见表?

如果您分组,然后你会看到这个问题之前,我们看看这个查询输出。多行将会返回一个用户,如果他们有任何连接表超过1分的纪录。因此,如果用户有2个评论记录然后2个记录也将被退回。

作为简化实例...

  

用户表

     

用户id名称

     

1佛瑞德

     

点表

     

用户id点数

     

1 10

     

评论表

     

用户id注释

     

1这里

     

1有

选择*从这些表将导致

  

用户id点注释

     

1 10在这里

     

1 10有

我不能完全肯定MYSQL语法,但你会希望类似

SELECT UserId, C.num_comments, P.total_points
FROM users
LEFT JOIN 
   (SELECT c_userId, COUNT(DISTINCT c_id) as num_comments
    FROM Comments
    GROUP BY c_userId)
    AS C
    ON UserId = c_userid
LEFT JOIN 
   (SELECT point_userId, sum(COALESCE(point_points, 0)) as total_points
    FROM Points
    GROUP BY point_userId)
    AS P
    ON UserId = point_userid
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top