简体   繁体   中英

Count 2 different things from 2 different table on one query MYSQL

Im trying to count 2 different things from 2 different table with one query.

My problem is that one of my joins affects on the other join count.

I want each of the joins to count without any connection to the count from the other join.

Here is the query:

   SELECT score.score, u.user_name, 

COUNT(mrank.user_id) as rank, COUNT(cr.id) as completedChallenges

    FROM user u

    LEFT OUTER JOIN challenges_score_user_rel score

    ON score.user_id = u.id AND score.challenge_group_id = 0

    LEFT OUTER JOIN challenges_score_user_rel mrank

    ON mrank.score >= score.score  AND  mrank.challenge_group_id = 0 AND (SELECT forGym.gym

    FROM user forGym WHERE forGym.id = mrank.user_id) = 22

    LEFT OUTER JOIN challenges_requests cr

    ON u.id = cr.receiver  AND cr.status = 3

    WHERE u.gym = 22 AND score.score IS NOT NULL GROUP BY u.id ORDER BY score.score DESC LIMIT 20

    +------------------+------+---------------------+
    | score| user_name | rank |  completedChallenges |
    +------------------+------+---------------------+
    | 999   |       A  | 3    |    3                 |
    +------------------+----------------------------+
    | 155   |      B   | 2    |       0              |
    +------------------+----------------------------+
    | 130   |      C   | 3    |       0              |
    +------------------+----------------------------+
    | 24    |      D   | 4    |       0              |
    +------------------+----------------------------+

As you can see from the results I get is that user A is in the first place but got rank 3.

The rank should be number in the ordered by score.

The count for the rank is from this join:

LEFT OUTER JOIN challenges_score_user_rel mrank

ON mrank.score >= score.score  AND  mrank.challenge_group_id = 0 AND (SELECT forGym.gym

FROM user forGym WHERE forGym.id = mrank.user_id) = 22

If I remove this join:

LEFT OUTER JOIN challenges_requests cr

ON u.id = cr.receiver  AND cr.status = 3

The count is fine and I get the correct rank for the all the users.

Why does 2 joins affect each other can I make them count on they own?

The easiest way to solve this is to use count(distinct) :

SELECT score.score, u.user_name, 
       COUNT(distinct mrank.user_id) as rank,
       COUNT(distinct cr.id) as completedChallenges

The problem is that you are getting a cartesian product for each user. If the numbers are large, then this is not the best performing solution. In that case, you want to pre-aggregate the data in the from clause or use a correlated subquery in the SELECT clause.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM