Overview:
I built an application that I run locally which allows me to keep track of my kids chores and behaviors that they exhibit on a daily basis. This system has negative and positive behaviors I can assign to them which correspond to a point value on a 100 point scale.
Logic:
- The query only looks at the current day to calculate the points. If ratings were received the day prior, those will not play into their daily total.
- 100 points is the maximum a child can have for the day, even if their ratings cause them to exceed this, it will always return as
100. - If they don't have any ratings for the day (either positive or negative), it will default their points to the starting point
100. - When they receive points, their total will adjust accordingly, either going up or down based on the value set for the behavior.
Scenarios:
- New day without any ratings means the child starts at
100points. They receive a negative behavior that has a-3value. This would return theirtotalPointsas97. - The above child then receives a positive rating worth
2points which brings them up to99for theirtotalPoints. - They receive another positive rating worth
5points. Since we max out at 100, we would return theirtotalPointsas100, regardless of how much it exceeded100.
Issue:
I built the query and thought everything was working fine but there seems to be a slight math issue with it. When the child received a -3 point rating it brought them to 97 which was expected. I then gave them a positive 4 and it brought their score to 99 instead of 100 like I would have expected.
Query:
SELECT c.id,
c.NAME,
Date_format(From_days(Datediff(CURRENT_DATE, c.age)),
'%y Years %m Months %d Days') AS age,
c.photoname,
c.photonamesmall,
(SELECT CASE
WHEN ( Ifnull(Sum(t.points), (SELECT settingvalue
FROM settings
WHERE settingname = 'MaxPoints')
) >= (
SELECT
settingvalue
FROM
settings
WHERE
settingname = 'MaxPoints') ) THEN 100
WHEN ( Sum(t.points) <= 0 ) THEN ( (SELECT settingvalue
FROM settings
WHERE settingname =
'MaxPoints')
+ Sum(t.points) )
ELSE ( (SELECT settingvalue
FROM settings
WHERE settingname = 'MaxPoints') -
Ifnull(Sum(t.points), (SELECT
settingvalue
FROM settings
WHERE
settingname = 'MaxPoints')) )
END
FROM behaviorratings AS r
JOIN behaviortypes AS t
ON r.behaviorid = t.behaviortypeid
WHERE r.childid = c.id
AND Date_format(r.timestamp, '%Y-%m-%d') = Curdate()) AS
totalPoints,
(SELECT definitionname
FROM behaviordefinitions AS d
WHERE totalpoints BETWEEN d.min AND d.max) AS
behaviorRating
FROM children AS c
Fiddle:
Here is a link to the SQL fiddle: http://sqlfiddle.com/#!9/fa06c/1/0
The result I expect to see for Child 2 (Brynlee) is 100 not 99.
She started with 100, received a -3 and the received a +4. While I know the math for this order of operations is correct, I need to it to be tweaked to reflect how I expected it to be reflected. 100 - 3 = 97 and then 97 + 4 = 101 (We max out at 100 so 100 would be the totalPoints.