get total amount of expenses per month in MySQL - mysql

I am currently working with 2 tables, expenses and income. To keep the structure simple and can see it, this is the fiddle: http://sqlfiddle.com/#!9/256cd64/2
The result I need from my query is the total amount for each month of the current year, for this and tried something like this:
select sum(e.amount) as expense, DATE_FORMAT(e.date,'%m') as month
from expenses e
where year(e.date) = 2019
group by month
My problem with this is that it only takes me the months where there was registration and I would like it to take 12 months whether or not they have a registration, in the case that they did not return 0 as a total amount.
At the moment I am working with the table of expenses but I would like to have a single query that returns the monthly expenses and income, this is an example of the final output that I would like to obtain:
| Month | Expense| Incomes |
|---------|--------|---------|
| 01| 0 | 0 |
| 02| 3000 | 4000 |
| 03| 1500 | 5430 |
| 04| 2430 | 2000 |
| 05| 2430 | 1000 |
| 06| 2430 | 1340 |
| 07| 0 | 5500 |
| 08| 2430 | 2000 |
| 09| 1230 | 2000 |
| 10| 8730 | 2000 |
| 11| 2430 | 2000 |
| 12| 6540 | 2000 |

You need to generate the month values and then use left join to match to expenses:
select coalesce(sum(e.amount), 0) as expense, m.month
from (select '01' as month union all
select '02' as month union all
select '03' as month union all
select '04' as month union all
select '05' as month union all
select '06' as month union all
select '07' as month union all
select '08' as month union all
select '09' as month union all
select '10' as month union all
select '11' as month union all
select '12' as month
) m left join
expenses e
on year(e.date) = 2019 and
DATE_FORMAT(e.date,'%m') = m.month
group by m.month;
Here is a db<>fiddle.
As for income, you should ask another question about that.

You can use MONTH to get month value from your date column and then GROUP BY them to get your desired output as below-
SELECT SUM(e.amount) AS expense,
MONTH(e.date) AS month
FROM expenses e
WHERE YEAR(e.date) = 2019
GROUP BY MONTH(e.date)

Try changing your sum(e.amount) as expense to: COALESCE(sum(e.amount),0) as expense
The COALESCE function returns the first non NULL value.

SELECT
t1.month,
COALESCE(t2.amount, 0) AS expenses,
COALESCE(t3.amount, 0) AS incomes
FROM
(
SELECT 1 AS month UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 8 UNION ALL
SELECT 9 UNION ALL
SELECT 10 UNION ALL
SELECT 11 UNION ALL
SELECT 12
) t1
LEFT JOIN
(
SELECT MONTH(date) AS month, SUM(amount) AS amount
FROM expenses
GROUP BY MONTH(date)
) t2
ON t1.month = t2.month
LEFT JOIN
(
SELECT MONTH(date) AS month, SUM(amount) AS amount
FROM incomes
GROUP BY MONTH(date)
) t3
ON t1.month = t3.month
ORDER BY
t1.month;

Related

Set default value if no result found

I have the following query
SELECT count(*) as count, Month(created_at) as month
FROM products
WHERE marketplace_id=21
and status='counterfeit'
and created_at < Now()
and created_at > DATE_ADD(Now(), INTERVAL - 5 MONTH)
group by month(created_at)
it return result as
+-------+-------+
| count | month |
+-------+-------+
| 410 | 1 |
| 174 | 2 |
| 301 | 3 |
| 329 | 4 |
| 141 | 12 |
+-------+-------+
in case a month does not have values it doesn't returns it at all, but I want the default value 0 to be set for that month.
I have tried this link Return a default value if no rows found
and
Returning a value if no result
I am not sure whether I am not able to implement it correctly or this is not what I want
Try this, seems to be a little stupid, but may help for you;)
SELECT SUM(count) AS count, month
FROM (
SELECT count(*) as count, Month(created_at) as month FROM products WHERE marketplace_id=21
and status='counterfeit' and created_at < Now() and created_at > DATE_ADD(Now(), INTERVAL - 5 MONTH)
group by month(created_at)
UNION
SELECT * FROM (
SELECT 0 AS count, 1 AS month
UNION SELECT 0 AS count, 2 AS month
UNION SELECT 0 AS count, 3 AS month
UNION SELECT 0 AS count, 4 AS month
UNION SELECT 0 AS count, 5 AS month
UNION SELECT 0 AS count, 6 AS month
UNION SELECT 0 AS count, 7 AS month
UNION SELECT 0 AS count, 8 AS month
UNION SELECT 0 AS count, 9 AS month
UNION SELECT 0 AS count, 10 AS month
UNION SELECT 0 AS count, 11 AS month
UNION SELECT 0 AS count, 12 AS month) M
WHERE M.month < Month(Now()) AND M.month > Month(DATE_ADD(Now(), INTERVAL - 5 MONTH)))
) tmp
GROUP BY mouth
ORDER BY month
You could create another table with default values
test_defaults
-----------------
| month | count |
and than just left join it with your table of values so if the value is found within the main table, it will be used, if not value from test_defaults would be used (we will use COALESCE function which returns first non null value):
SELECT t1.month, COALESCE(t2.count, t1.count)
FROM test_defaults t1
LEFT JOIN test_data t2 ON t1.month = t2.month
ORDER BY t1.month;
Here's a working SqlFiddle demo

Count active users based on logins last 90 days

I am trying to make a query that will result in a list showing how many active users we have month by month. We define an active users as a user that have been logged in in the last 90 days.
I can easily define the number of active users we have right now by this
SELECT COUNT(DISTINCT(user_id) FROM login_table
WHERE login_date BETWEEN DATE_SUB(login_date, INTERVAL 90 DAY) AND NOW())
My problem comes when I have to count the amount of users we have month by month
Here i have to count one single login several times.
If I have a user that login at 10 of January, and never login again, this user should count as an active user in the following months: January, February, March and April, even though I only have one registration of the user
Example data:
login_date | user_id
2015-01-01 | 1
2015-02-10 | 1
2015-02-11 | 2
2015-02-13 | 1
2015-03-19 | 1
This should result in something like this:
Date | Active users
2015-01 | 1
2015-02 | 2
2015-03 | 2
2015-04 | 2
2015-05 | 2
2015-06 | 1
2015-07 | 0
2015-08 | 0
Is there anyway of doing a count like that?
Problems like this are easier to solve, if you have a calendar table with all the dates you need. If you don't have such a table you can create it with a query like this:
create table `calendar` (
`date` DATE NOT NULL,
PRIMARY KEY (`date`)
)
select DATE_ADD('1900-01-01',INTERVAL t4.c*10000 + t3.c*1000 + t2.c*100 + t1.c*10 + t0.c DAY) as `date`
from
(select 0 c union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t0,
(select 0 c union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t1,
(select 0 c union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t2,
(select 0 c union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t3,
(select 0 c union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t4
That will create a table with dates from 1900-01-01 to 2173-10-15 (100K days) and consume only about 2.5 MB. You can adjust it to your needs.
Using the caledar table you can get three-month-ranges:
select
DATE_FORMAT(date_sub(c.date, INTERVAL 1 day), '%Y-%m') as month,
date_sub(c.date, INTERVAL 3 month) as first_day,
date_sub(c.date, INTERVAL 1 day) as last_day
from calendar c
where day(c.date) = 1
and c.date between '2015-02-01' and '2015-09-01'
Result:
| month | first_day | last_day |
| 2015-01 | 2014-11-01 | 2015-01-31 |
| 2015-02 | 2014-12-01 | 2015-02-28 |
| 2015-03 | 2015-01-01 | 2015-03-31 |
| 2015-04 | 2015-02-01 | 2015-04-30 |
| 2015-05 | 2015-03-01 | 2015-05-31 |
| 2015-06 | 2015-04-01 | 2015-06-30 |
| 2015-07 | 2015-05-01 | 2015-07-31 |
| 2015-08 | 2015-06-01 | 2015-08-31 |
Adjust it, if you really want to use something like 90 days intervals.
Now it's a simple left join with the login table to get what you want:
select i.month as `Date`, count(distinct l.user_id) as `Active users`
from (
select
date_format(date_sub(c.date, interval 1 day), '%Y-%m') as month,
date_sub(c.date, interval 3 month) as first_day,
date_sub(c.date, interval 1 day) as last_day
from calendar c
where day(c.date) = 1
and c.date between '2015-02-01' and '2015-09-01'
) i
left join login_table l on l.login_date between i.first_day and i.last_day
group by i.month
http://sqlfiddle.com/#!9/d1bb0/3
Can you use:
Select DATE_FORMAT(login_date,'%Y %m') as date, ....
....
Group by DATE_FORMAT(login_date,'%Y %m')
You can build an in-line tally table containing all the required month/year value pairs. Then LEFT JOIN your table to this table and GROUP BY to get the required result:
SELECT CONCAT(months.m, '-', years.y) AS 'date',
COUNT(DISTINCT(user_id)) AS 'users_count'
FROM (
SELECT '01' AS m UNION ALL SELECT '02' UNION ALL SELECT '03' UNION ALL
SELECT '04' UNION ALL SELECT '05' UNION ALL SELECT '06' UNION ALL
SELECT '07' UNION ALL SELECT '08' UNION ALL SELECT '09' UNION ALL
SELECT '10' UNION ALL SELECT '11' UNION ALL SELECT '12') AS months
CROSS JOIN (
SELECT '2015' AS y UNION ALL SELECT '2016') AS years
LEFT JOIN login_table AS lt
ON DATE_FORMAT(lt.login_date, '%d-%Y') = CONCAT(months.m, '-', years.y)
GROUP BY CONCAT(months.m, '-', years.y)
The above query is suitable for producing a report for all the months from years 2015/2016. You can edit the tally table as you wish in order to adapt it to your actual requirement.
Edit:
You need correlation if you want to count active users in rolling 3 month intervals:
SELECT CONCAT(months.m, '-', years.y) AS 'date',
(SELECT COUNT(DISTINCT(user_id))
FROM login_table
WHERE login_date BETWEEN CONCAT(years.y, '-', months.m, '-01') AND
DATE_ADD(CONCAT(years.y, '-', months.m, '-01'), INTERVAL 90 DAY))
FROM (
SELECT '01' AS m UNION ALL SELECT '02' UNION ALL SELECT '03' UNION ALL
SELECT '04' UNION ALL SELECT '05' UNION ALL SELECT '06' UNION ALL
SELECT '07' UNION ALL SELECT '08' UNION ALL SELECT '09' UNION ALL
SELECT '10' UNION ALL SELECT '11' UNION ALL SELECT '12') AS months
CROSS JOIN (
SELECT '2015' AS y UNION ALL SELECT '2016') AS years
LEFT JOIN login_table AS lt
ON DATE_FORMAT(lt.login_date, '%d-%Y') = CONCAT(months.m, '-', years.y)
GROUP BY CONCAT(months.m, '-', years.y)
and by using the method MONTH()?
something like this:
SELECT MONTH(login-date) as perMonth, COUNT(DISTINCT(user_id)) from login_table GROUP BY MONTH(login-date)
SELECT Date_format(login_date, '%Y-%m-%01') as mymonth, count(user_id) as totalusers
FROM login_table
WHERE login_date >= DATE_SUB(now(), INTERVAL 90 DAY)
Group by Date_format(login_date, '%Y-%m-%01')
Here is info about date_format function https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-format
This will work:
SELECT DATE_FORMAT(login_date, "%Y-%m"), COUNT(user_id)
FROM login_table
WHERE login_date BETWEEN DATE_SUB(login_date, INTERVAL 90 DAY) AND NOW()
GROUP BY login_date
Another simple and stupid solution is to copy the login_table six times adding 15 days to the login_date each time. This way we can ensure that every login is duplicated at least once in every month within the following 90 days. Then we can group by year and moth to count active users.
select
date_format(login_date, "%Y-%m") as `Date`,
count(distinct l.user_id) as `Active users`
from (
select l.user_id, l.login_date from login_table l
union all select l.user_id, date_add(l.login_date, interval 15 day) from login_table l
union all select l.user_id, date_add(l.login_date, interval 30 day) from login_table l
union all select l.user_id, date_add(l.login_date, interval 45 day) from login_table l
union all select l.user_id, date_add(l.login_date, interval 60 day) from login_table l
union all select l.user_id, date_add(l.login_date, interval 75 day) from login_table l
union all select l.user_id, date_add(l.login_date, interval 90 day) from login_table l
) l
group by date_format(login_date, "%Y-%m")

MySql Single Table, Select last 7 days and include empty rows

I have searched similar problems here on stackoverflow but I could not understand how to make this work, what I'm trying to do...
So, I want to get last 7 days transactions from database and get total sales amount and also include empty rows if there is no data for some day.
What I have so far:
http://sqlfiddle.com/#!2/f4eda/6
This outputs:
| PURCHASE_DATE | AMOUNT |
|---------------|--------|
| 2014-04-25 | 19 |
| 2014-04-24 | 38 |
| 2014-04-22 | 19 |
| 2014-04-19 | 19 |
What I want:
| PURCHASE_DATE | AMOUNT |
|---------------|--------|
| 2014-04-25 | 19 |
| 2014-04-24 | 38 |
| 2014-04-23 | 0 |
| 2014-04-22 | 19 |
| 2014-04-21 | 0 |
| 2014-04-20 | 0 |
| 2014-04-19 | 19 |
Any help appreciated :)
This is not easy. I took help from this thread generate days from date range and combined it with your query.
So the idea was to get the list of dates from last 7 days then left join these dates with a static amount 0 to the query you have and then finally sum them. This could be used for any date range, just need to change them in both the queries
select
t1.purchase_date,
coalesce(SUM(t1.amount+t2.amount), 0) AS amount
from
(
select DATE_FORMAT(a.Date,'%Y-%m-%d') as purchase_date,
'0' as amount
from (
select curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY as Date
from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
) a
where a.Date BETWEEN NOW() - INTERVAL 7 DAY AND NOW()
)t1
left join
(
SELECT DATE_FORMAT(purchase_date, '%Y-%m-%d') as purchase_date,
coalesce(SUM(amount), 0) AS amount
FROM transactions
WHERE purchase_date BETWEEN NOW() - INTERVAL 7 DAY AND NOW()
AND vendor_id = 0
GROUP BY purchase_date
)t2
on t2.purchase_date = t1.purchase_date
group by t1.purchase_date
order by t1.purchase_date desc
DEMO
Simply put together a subquery with the dates you want and use left outer join:
select d.thedate, coalesce(SUM(amount), 0) AS amount
from (select date('2014-04-25') as thedate union all
select date('2014-04-24') union all
select date('2014-04-23') union all
select date('2014-04-22') union all
select date('2014-04-21') union all
select date('2014-04-20') union all
select date('2014-04-19')
) d left outer join
transactions t
on t.purchase_date = d.thedate and vendor_id = 0
GROUP BY d.thedate
ORDER BY d.thedate DESC;
This is for last 7 days;
select d.thedate, coalesce(SUM(amount), 0) AS amount
from (select DATE(NOW()) as thedate union all
select DATE(DATE_SUB( NOW(), INTERVAL 1 DAY)) union all
select DATE(DATE_SUB( NOW(), INTERVAL 2 DAY)) union all
select DATE(DATE_SUB( NOW(), INTERVAL 3 DAY)) union all
select DATE(DATE_SUB( NOW(), INTERVAL 4 DAY)) union all
select DATE(DATE_SUB( NOW(), INTERVAL 5 DAY)) union all
select DATE(DATE_SUB( NOW(), INTERVAL 6 DAY))) d left outer join
transactions t
on t.purchase_date = d.thedate and vendor_id = 0
GROUP BY d.thedate
ORDER BY d.thedate DESC;
with recursive all_dates(dt) as (
select '2014-04-19' as dt
union all
select dt + interval 1 day
from all_dates
where dt + interval 1 day <= '2014-04-25'
)
select d.dt as purchase_date, coalesce(m.amount, 0) as purchased
from all_dates as d
left join mytable m
on d.dt = m.purchase_date
order by purchase_date desc;

Daily Report in a month from different tables

I have four Tables with four date coloumns respectively.
Table 1 ---------- Date 1
Table 2 ---------- Date 2
Table 3 ---------- Date 3
Table 4 ---------- Date 4
Now i want to get a day report in a month for all the four tables.if there is no data in any particular table for particular date it should dispaly NULL.How can i achieve it?
Structure:-
Table-1:-
ID Amount1 Date1
1 340 24/04/2013
2 200 04/04/2013
3 1000 15/04/2013
Table-2:-
ID Amount2 Date2
1 2000 22/04/2013
2 200 04/04/2013
3 1500 15/04/2013
Table-3:-
ID Amount3 Date3
1 3400 24/04/2013
2 200 19/04/2013
3 1800 15/04/2013
Table-4:-
ID Amount4 Date4
1 3200 24/04/2013
2 2200 04/04/2013
3 1000 18/04/2013
Now my result should be like
Date Amount1 Amount2 Amount3 Amount4
01/04/2013 Null Null Null Null
|
|
|
04/04/2013 200 200 null 2200
|
|
|
|
15/0402013 1000 1500 1800 null
|
|
|
|
|24/0402013 340 null 3400 3200
|
|
|
|
31/04/2013
Using a subquery to get a range of dates (I am assuming you want every day in April 2013) and then left joining that against the tables of data.
SELECT, dates.aDate, Table-1.Amount1, Table-2.Amount2, Table-3.Amount3, Table-4.Amount4
FROM
(
SELECT DATE_ADD('2013-04-01', INTERVAL (Units.i + Tens.i * 10) DAY) AS aDate
FROM
(SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) Units,
(SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) Tens
HAVING aDate <= '2013-04-30'
) dates
LEFT OUTER JOIN Table-1 ON Table-1.Date1 = dates.aDate
LEFT OUTER JOIN Table-2 ON Table-2.Date2 = dates.aDate
LEFT OUTER JOIN Table-3 ON Table-3.Date3 = dates.aDate
LEFT OUTER JOIN Table-4 ON Table-4.Date4 = dates.aDate
This assumes that there are not duplicate dates in any particular table.
You can try the following query
with dates as (
(select date from date1)union(select date from date2)union
(select date from date3)union (select date from date4) order by date asc)
select date,
(select amount from date1 where date=dt.date limit 1),
(select amount from date2 where date=dt.date limit 1),
(select amount from date3 where date=dt.date limit 1),
(select amount from date4 where date=dt.date limit 1)
from dates as dt;
You can add the date constraints on dates.
P.S.: Tested on PgSQL

MySQL Query for Graphs

I've got the following query:
SELECT GVA12.FECHA_EMIS, GVA12.COD_VENDED, sum(GVA12.IMPORTE)
FROM GVA12
WHERE Month(GVA12.FECHA_EMIS)=Month(curDate())
AND Year(GVA12.FECHA_EMIS)=Year(curDate())
AND GVA12.COD_VENDED="EX"
AND GVA12.T_COMP="FAC"
GROUP BY GVA12.FECHA_EMIS
This is for a monthly graph. I've got two questions. One, how can I show all the dates of the months as zero (the ones that don't have any sales), and two, is there any way to make the values go adding up, so the last value is the total of all the values.
Edit:
#Bluefeet with your query, I created the following,
SELECT Month(Days.DMY), Year(Days.DMY), GVA12.COD_VENDED, sum(GVA12.IMPORTE)
FROM Days
left join GVA12
on Month(Days.DMY) = Month(GVA12.FECHA_EMIS)
and Year(Days.DMY) = Year(GVA12.FECHA_EMIS)
WHERE Month(GVA12.FECHA_EMIS)=Month(curDate())
AND Year(GVA12.FECHA_EMIS)=Year(curDate())
AND GVA12.COD_VENDED="EX"
AND GVA12.T_COMP="FAC"
GROUP BY Month(Days.DMY), Year(Days.DMY) WITH ROLLUP
I got the result attached (screenshot).
It doesn't show all the days of the month as I wanted. What can I do?
Edit #3
It works now, but I want to add another filter. This filter is added here http://sqlfiddle.com/#!2/9d46c/1
To get the total you can use the GROUP BY WITH ROLLUP which should give you the Total of all dates:
SELECT GVA12.FECHA_EMIS, GVA12.COD_VENDED, sum(GVA12.IMPORTE)
FROM GVA12
WHERE Month(GVA12.FECHA_EMIS)=Month(curDate())
AND Year(GVA12.FECHA_EMIS)=Year(curDate())
AND GVA12.COD_VENDED="EX"
AND GVA12.T_COMP="FAC"
GROUP BY GVA12.FECHA_EMIS WITH ROLLUP
As far as returning dates that do not exist, There are many questions on SO that answer that including the following. Sometimes it is easier in MySQL to create a table to join on:
generate days from date range
Get a list of dates between two dates
Edit #1: if you have a table with dates, then you could use something similar to this:
SELECT Month(d.yourDateCol), Year(d.yourDateCol), g.COD_VENDED, sum(g.IMPORTE)
FROM dates d
left join GVA12 g
on Month(d.yourDateCol) = Month(GVA12.FECHA_EMIS)
and Year(d.yourDateCol) = Year(GVA12.FECHA_EMIS)
WHERE Month(g.FECHA_EMIS)=Month(curDate())
AND Year(g.FECHA_EMIS)=Year(curDate())
AND g.COD_VENDED="EX"
AND g.T_COMP="FAC"
GROUP BY Month(d.yourDateCol), Year(d.yourDateCol) WITH ROLLUP
Edit #2: Without seeing your full table structure or some sample data, here is a version of the query that is working:
select month(d.dmy) Month,
year(d.dmy) Year,
coalesce(sum(g.Importe), 0) TotalImporte
from dates d
left join GVA12 g
on month(d.dmy) = month(g.FECHA_EMIS)
and year(d.dmy) = year(g.FECHA_EMIS)
group by month(d.dmy), year(d.dmy) WITH ROLLUP
See SQL Fiddle with Demo. This returns the month/year for each month/year in the dates table even if it does not exist in the GVA12 table,
Edit #3: If you want the running total, not just the final total, then you should be able to use the following:
SET #running_total := 0;
SELECT month(Days.DMY) Month,
Year(Days.DMY) Year,
Date(Days.DMY) Date,
g.COD_VENDED,
#running_total := #running_total + Coalesce(TotalImport, 0) as TotalImport
FROM Days
left join
(
select FECHA_EMIS,
COD_VENDED,
sum(IMPORTE) TotalImport
from GVA12
group by Date(FECHA_EMIS), Year(FECHA_EMIS)
) g
on date(Days.DMY) = date(g.FECHA_EMIS)
and g.COD_VENDED='EX'
and Month(g.FECHA_EMIS)=Month(curDate())
and Year(g.FECHA_EMIS)=Year(curDate())
WHERE month(days.dmy)=Month(curDate())
See SQL Fiddle with Demo
The result is:
| MONTH | YEAR | DATE | COD_VENDED | TOTALIMPORT |
----------------------------------------------------------------------------
| 1 | 2013 | January, 01 2013 00:00:00+0000 | (null) | 0 |
| 1 | 2013 | January, 02 2013 00:00:00+0000 | EX | 1000 |
| 1 | 2013 | January, 03 2013 00:00:00+0000 | EX | 4000 |
| 1 | 2013 | January, 04 2013 00:00:00+0000 | (null) | 4000 |
| 1 | 2013 | January, 05 2013 00:00:00+0000 | (null) | 4000 |
| 1 | 2013 | January, 06 2013 00:00:00+0000 | (null) | 4000 |
| 1 | 2013 | January, 07 2013 00:00:00+0000 | (null) | 4000 |
a couple ideas:
one - you need some data values to compare against - so you could build a new table to hold all the dates - statically - then you do an outer join to that to make sure you get the zeroes.
two - i'm not sure about mysql - but in Oracle this is a LAG function. maybe that is a helpful pointer for further research.
Have a look at this link, there is explained how to list all dates between 2 dates
Get a list of dates between two dates
you can list using the following but I think there are better solution in the above link:
select a.Date
from (
select curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY as Date
from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
) a
where a.Date between '2012-12-01' and '2012-12-31';