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
100
points. They receive a negative behavior that has a-3
value. This would return theirtotalPoints
as97
. - The above child then receives a positive rating worth
2
points which brings them up to99
for theirtotalPoints
. - They receive another positive rating worth
5
points. Since we max out at 100, we would return theirtotalPoints
as100
, 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
.