Pergunta

I found a lot of helpful information on stackoverflow, but a tiny bit is still missing to solve the following issue:

I have two tables userscores and userpoints like that:

#table userscores (saves userpoints each month) 

date          userid   points
2012-05-01    1        23
2012-06-01    1        34


#table userpoints (recent points) 

userid   points
1        23
2        10
3        15

I was able to find out how to calculate the differences between recent userpoints and stored userpoints (from table "userscores") of the current month using:

SELECT userpoints.userid, userpoints.points - userscores.points AS mpoints 
    FROM `userpoints`,`userscores` 
    WHERE userpoints.userid=userscores.userid 
        AND YEAR(userscores.date) = YEAR(CURDATE()) 
        AND MONTH(userscores.date) = MONTH(CURDATE())
        AND userpoints.userid != ".$adminID."
    ORDER BY mpoints DESC;"

However, this query is only comparing the userid from both tables and ignoring the userids that exist in table userpoints and but do not exist in table userscores.

The query should be modified so that newly created userids (in table userpoints) are considered as scores as well.


I found out how to query to get the userids that do not exist in table userscores:

 SELECT userpoints.userid FROM `userpoints` 
      WHERE userpoints.userid 
           NOT IN(SELECT qa_userscores.userid FROM `qa_userscores`)


Now I have to combine both but trying the following does not work:

SELECT userpoints.userid, userpoints.points - userscores.points AS mpoints 
FROM `userpoints`,`userscores` 
WHERE ( 
    userpoints.userid = userscores.userid
    AND YEAR(userscores.date) = YEAR(CURDATE()) 
    AND MONTH(userscores.date) = MONTH(CURDATE())
    AND userpoints.userid != ".$adminID."
)
OR ( 
    userpoints.userid IN(SELECT userpoints.userid FROM `userpoints` 
        WHERE userpoints.userid 
            NOT IN(SELECT DISTINCT userscores.userid FROM `userscores`)) 
)
ORDER BY mpoints DESC;


Any help appreciated.

Foi útil?

Solução

SELECT userpoints.userid, userpoints.points - coalesce(userscores.points,0) 
                                                 AS mpoints 
    FROM `userpoints`
    left join `userscores` on userpoints.userid=userscores.userid         
        AND YEAR(userscores.date) = YEAR(CURDATE()) 
        AND MONTH(userscores.date) = MONTH(CURDATE())
    where userpoints.userid != ".$adminID."
    ORDER BY mpoints DESC;"

The Left join automatically retains the rows on the left side even when there is no corresponding row on the right. All conditions you check on the right side must be in the Join Condition. Finally, you need to use a default value for the Right Side value when ther is none.

Outras dicas

You can combine the results from two queries using UNION.

SELECT userpoints.userid, userpoints.points - userscores.points AS mpoints 
    FROM `userpoints`,`userscores` 
    WHERE userpoints.userid=userscores.userid 
        AND YEAR(userscores.date) = YEAR(CURDATE()) 
        AND MONTH(userscores.date) = MONTH(CURDATE())
UNION 

SELECT userpoints.userid, points as mpoints FROM `userpoints` 
      WHERE userpoints.userid 
           NOT IN(SELECT userscores.userid FROM `userscores`)

See the mysql documentation for more information on the usage of UNION.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top