I need to create a MySQL stored procedure it selects each User SUM of all the Points they've earned.
The query should group Game by StartTime and only select the first row of each group ordered by Points. I'm trying to ignore duplicate StartTime values for each User but still keep the first one. This should avoid cheating if the User saves the same game twice.
If the User hasn't been in any Game, it should still return NULL.
CREATE PROCEDURE `spGetPoints`(
IN _StartDate DATETIME,
IN _EndDate DATETIME,
IN _Limit INT,
IN _Offset INT
)
BEGIN
SELECT `User`.`UserId`, `User`.`Username`,
(SELECT SUM(`Game`.`Points`)
FROM `Game`
WHERE `Game`.`UserId` = `User`.`UserId` AND
`Game`.`StartDate` > _StartDate AND `Game`.`StartDate` < _EndDate
GROUP BY `Game`.`StartDate`
ORDER BY `Game`.`Points` DESC
LIMIT 1
) AS `Value`
FROM `User`
ORDER BY `Value` DESC, `User`.`Username` ASC
LIMIT _Limit OFFSET _Offset;
END
Sample User Table
+--------+----------+
| UserId | Username |
+--------+----------+
| 1 | JaneDoe |
| 2 | JohnDoe |
+--------+----------+
Sample Game Table
+--------+--------+-------------------------+--------+
| GameId | UserId | StartDate | Points |
+--------+--------+-------------------------+--------+
| 1 | 1 | 2019-01-09 12:43:00 AM | 1789 |
| 2 | 1 | 2019-01-09 11:35:00 AM | 1048 |
| 3 | 1 | 2019-01-09 9:22:00 AM | 900 |
| 4 | 1 | 2019-01-09 12:43:00 AM | 1789 |
| 5 | 1 | 2019-01-09 11:35:00 AM | 1048 |
| 6 | 1 | 2019-01-09 9:22:00 AM | 900 |
| 7 | 1 | 2019-01-09 12:43:00 AM | 1789 |
| 8 | 1 | 2019-01-09 11:35:00 AM | 1048 |
| 9 | 2 | 2019-01-17 12:05:00 AM | 552 |
| 10 | 2 | 2019-01-24 12:08:00 AM | 512 |
| 11 | 2 | 2019-01-27 5:13:00 PM | 0 |
+--------+--------+-------------------------+--------+
Current Result
+--------+----------+-------+
| UserId | Username | Value |
+--------+----------+-------+
| 1 | JaneDoe | 5367 |
| 2 | JohnDoe | 552 |
+--------+----------+-------+
Expected Result
+--------+----------+-------+
| UserId | Username | Value |
+--------+----------+-------+
| 1 | JaneDoe | 3737 |
| 2 | JohnDoe | 1064 |
+--------+----------+-------+
I was able to get the expected result with the following statement by selecting the SUM from a subquery and hardcoding the UserId.
SELECT SUM(`x`.`Points`) FROM
(SELECT `Points`
FROM `Game`
WHERE `Game`.`UserId` = 1 AND
`Game`.`StartDate` > STR_TO_DATE('01/09/2019', '%m/%d/%Y') AND `Game`.`StartDate` < STR_TO_DATE('02/09/2019', '%m/%d/%Y')
GROUP BY `Game`.`StartDate`
ORDER BY `Game`.`Points` ASC) AS `x`;
When I try to put that statement in a subquery like in the following statement, I get this error message Error Code: 1054. Unknown column 'User.UserId' in 'where clause'. I'm getting this error because the UserId isn't visible in the second subquery.
SELECT `User`.`UserId`, `User`.`Username`,
(SELECT SUM(`x`.`Points`) FROM (SELECT `Game`.`Points`
FROM `Game`
WHERE `Game`.`UserId` = `User`.`UserId` AND
`Game`.`StartDate` > STR_TO_DATE('01/09/2019', '%m/%d/%Y') AND `Game`.`StartDate` < STR_TO_DATE('02/09/2019', '%m/%d/%Y')
GROUP BY `Game`.`StartDate`
ORDER BY `Game`.`Points` DESC) AS `x`
) AS `Value`
FROM `User`
ORDER BY `Value` DESC, `User`.`Username` ASC;