Reputation: 2907
I have been trying to come up with a query to display data in a particular fashion and I have been struggling with it.
Suppose with these data
ID Amount Date
1 10 10/10/2014 13:45
1 20 10/10/2014 14:56
1 05 10/10/2014 22:45
1 10 11/10/2014 23:04
1 30 14/10/2014 03:00
1 15 14/10/2014 04:34
1 15 15/10/2014 13:34
2 10 10/10/2014 16:05
I want to call the query with a start date and and end date and to display the results with a daily row that contains the sum of the amount for that day for that ID. So result would be:
For Id=1, StartDate=10/10/2014 and EndDate=14/10/2014:
Date Sum
10/10/2014 35
11/10/2014 10
12/10/2014 0
13/10/2014 0
14/10/2014 45
Now down to the things I have already tried, I created a script in jFiddle:
CREATE TABLE TableName
(`id` int, `amount` int, `timestamp` datetime)
;
INSERT INTO TableName
(`id`, `amount`, `timestamp`)
VALUES
(1, 10, '2013-01-06 12:23:56'),
(1, 15, '2013-01-06 02:23:41'),
(1, 15, '2013-01-07 14:23:42'),
(1, 0, '2013-01-08 04:23:56'),
(1, 5, '2013-01-08 16:23:25'),
(1, 20, '2013-01-08 12:23:57'),
(1, 10, '2013-01-08 23:23:40'),
(1, 0, '2013-01-09 07:23:56'),
(1, 5, '2013-01-12 17:23:25'),
(1, 20, '2013-01-13 22:23:57'),
(1, 10, '2013-01-14 09:23:40'),
(1, 10, '2013-01-14 19:23:23'),
(1, 35, '2013-01-15 15:23:55'),
(1, 40, '2013-01-15 21:29:38'),
(2, 40, '2013-01-06 02:31:59');
And I used it as a playground using various methods I found all over the internet with not much luck.
Any idea how I can get the data in that structure?
Upvotes: 0
Views: 134
Reputation: 1270351
You need to generate all the dates. This is a pain, but the following works for your data:
select d.dte, coalesce(sum(tn.amount), 0)
from ((select date(timestamp) as dte from tablename) union
(select date(timestamp) + interval 1 day from tablename) union
(select date(timestamp) - interval 1 day from tablename)
) d left outer join
tablename tn
on date(tn.timestamp) = d.dte
group by d.dte
order by 1;
EDIT:
If you want to limit these to the dates in the table, then add:
where d.dte between (select min(date(timestamp) from tablename) and
(select max(date(timestamp) from tablename)
If your gaps are larger, put more selects
in the d
subquery, or use a calendar table (the latter is much easier).
Here is the SQL Fiddle.
Upvotes: 3
Reputation: 51908
select
date(timestamp) as my_date,
sum(amount)
from TableName
where id = 1
and timestamp between <start_date> and <end_date>
group by my_date
In between
use the date()
function again, if you're passing timestamps.
Upvotes: 1