Reputation: 45
I want to get some data from my database for the past 31 days. When column 'finalized' is NULL I want to get data from column 'today', but if column 'finalized' isn't NULL I want to get data from column 'finalized'. I always want to get the last entered row.
TABLE MyEarnings
id INT(11) AI
date datetime
today decimal(4,2) NULL
finalized decimal(4,2) NULL
id date today finalized
-----------------------------------------------
6 2016-02-04 04:52:00 0.39 NULL
5 2016-02-03 12:34:00 NULL 19.74
4 2016-02-03 12:33:00 15.96 NULL
3 2016-02-03 12:32:00 12.32 NULL
2 2016-02-02 15:16:00 NULL 9.16
1 2016-02-02 14:29:00 2.20 NULL
SQL
SELECT
date,
CASE
WHEN finalized=NULL
THEN today
WHEN finalized!=NULL
THEN finalized
END
AS earn
FROM MyEarnings
GROUP BY DATE_FORMAT(date, '%Y-%m-%d')
ORDER BY date ASC
LIMIT 0 , 31
This is what I end up with
date earn
---------------------------
2016-02-02 00:00:00 NULL
2016-02-03 00:00:00 NULL
2016-02-04 00:00:00 NULL
What I'm looking to get
date earn
----------------------------
2016-02-02 00:00:00 9.16
2016-02-03 00:00:00 19.74
2016-02-04 00:00:00 0.39
I also want to get a summary for each month of all values in 'finalized'-column with the max 'id' for each day.
Upvotes: 1
Views: 70
Reputation: 13110
Using greatest id to determine last row added (cons: stretching traditional use of id):
SELECT DATE(me.date) date,
COALESCE(me.finalized,me.today) earn
FROM MyEarnings me
JOIN (
SELECT MAX(id) max_id
FROM MyEarnings
GROUP BY DATE(date)
ORDER BY DATE(date)
LIMIT 31
) o
ON o.max_id = me.id
Using greatest date to determine last row added (cons: possible dupes):
SELECT DATE(me.date) date,
COALESCE(me.finalized,me.today) earn
FROM MyEarnings me
JOIN (
SELECT MAX(date) max_date
FROM MyEarnings
GROUP BY DATE(date)
ORDER BY DATE(date)
LIMIT 31
) o
ON o.max_date = me.date
Upvotes: 0
Reputation: 4491
use CASE
WHEN
like this:
CASE
WHEN finalized IS NULL
THEN today
ELSE finalized
END
AS earn
Replace query:
SELECT date, (CASE
WHEN finalized IS NULL THEN today
ELSE finalized
END;
) AS earn
FROM MyEarnings
GROUP BY DATE_FORMAT(date, '%Y-%m-%d')
ORDER BY date ASC LIMIT 0,31
Upvotes: 2
Reputation: 1269573
You need conditional aggregation, but it is a bit tricky. I think this does what you want:
SELECT DATE_FORMAT(date, '%Y-%m-%d'),
COALESCE(MAX(finalized), MAX(today)) as earn
FROM MyEarnings
GROUP BY DATE_FORMAT(date, '%Y-%m-%d')
ORDER BY date ASC
LIMIT 0 , 31;
This returns the maximum value of today
. You may want the most recent value. If so, the simplest method is probably the GROUP_CONCAT()
/SUBSTRING_INDEX()
method:
SELECT DATE_FORMAT(date, '%Y-%m-%d'),
COALESCE(MAX(finalized),
SUBSTRING_INDEX(GROUP_CONCAT(today ORDER BY date DESC), ',', 1) + 0
) as earn
FROM MyEarnings
GROUP BY DATE_FORMAT(date, '%Y-%m-%d')
ORDER BY date ASC
LIMIT 0 , 31;
It is a bit yucky to convert numbers to strings and back for this purpose. Alternative methods require additional joins or using variables.
Upvotes: 1
Reputation: 40481
You can't compare null with !=, you should use is null and is not null like this:
SELECT
date,
CASE
WHEN finalized is null THEN today
ELSE finalized
END AS earn
FROM MyEarnings
GROUP BY DATE_FORMAT(date, '%Y-%m-%d')
ORDER BY date ASC LIMIT 0 , 31
Also, if your first condition is when its null, you don't need to check if its not null , ELSE will be enough since the opposite of null is not null
Upvotes: 2