Count() does not return zero MySQL - mysql

I am a web developer and tried to search for the solution on a mysql query.I am unable to get the right solution for the count() function to return zero.
The count() function doesnot return zero for all dates.
The query is as below . can anyone help me on this.
SELECT
count(stat_id) as typeSuccess,
device_type as typeName,
YEARWEEK(date_auth) as date
FROM auth_stat
WHERE
AUTH_RESULT = 'SUCCESS' AND
date_auth BETWEEN DATE_SUB(CURDATE(), INTERVAL 6 WEEK) AND CURDATE()
GROUP BY YEARWEEK(date_auth), device_type
ORDER BY YEARWEEK(date_auth)
The query that i tried to form is
select
date_auth,
count(stat_id) as typeSuccess,
device_type as typeName,
YEARWEEK(date_auth) as date
from
(
select #curDate := Date_Add(#curDate, interval 1 day) as MyJoinDate
from
(
select #curDate := CURDATE()
) sqlvars, auth_stat limit 18
) dateAll
LEFT JOIN auth_stat U on dateAll.MyJoinDate = U.date_auth
group by dateAll.MyJoinDate
Actual ouput :
+------------+-------------+
| date | typeSuccess |
+------------+-------------+
| 2015-03-18 | 11 |
+------------+-------------+
Expected Output:
+------------+-------------+
| date | typeSuccess |
+------------+-------------+
| 2015-03-18 | 11 |
| 2015-03-19 | 0 |
| 2015-03-20 | 0 |
+------------+-------------+

I believe all you want to do is just this
SELECT
SUM(AUTH_RESULT='SUCCESS') as numSuccess,
YEARWEEK(date_auth) as date
FROM auth_stat
WHERE date_auth BETWEEN DATE_SUB(CURDATE(), INTERVAL 6 WEEK) AND CURDATE()
GROUP BY YEARWEEK(date_auth), device_type
ORDER BY YEARWEEK(date_auth)
basically all i'm doing is telling MySQL to sum up the boolean value (0 or 1) when auth_result is a success.. SUM() will return a 0 for a particular week if there is no successes in that week
The main issue is you were filtering out all non successful auth_results which would then not be counted. so remove that from the where and you should be good!
if you want it per day then you can do this
SELECT
SUM(AUTH_RESULT='SUCCESS') as numSuccess,
DATE(date_auth) as date
FROM auth_stat
WHERE date_auth BETWEEN DATE_SUB(CURDATE(), INTERVAL 6 WEEK) AND CURDATE()
GROUP BY DATE(date_auth), device_type
ORDER BY DATE(date_auth)
SQLFIDDLE FOR BOTH RESULTS

try
SELECT COUNT(statid), dates.auth_date
FROM
( SELECT DISTINCT auth_date
FROM Table1
WHERE auth_date BETWEEN '2015-03-06' AND '2015-03-09' -- or whatever
) AS dates
LEFT JOIN Table1 ON TRUE
AND Table1.auth_date = dates.auth_date
AND table1.auth_result = 'SUCCESS'
GROUP BY dates.auth_date
ORDER BY dates.auth_date
as desribed here: http://sqlfiddle.com/#!9/84faf/2
for eg data:
+--------+-------------+------------+
| statid | auth_result | auth_date |
+--------+-------------+------------+
| 1 | SUCCESS | 2015-03-05 |
| 2 | SUCCESS | 2015-03-05 |
| 3 | SUCCESS | 2015-03-05 |
| 4 | OTHER | 2015-03-06 |
| 5 | OTHER | 2015-03-06 |
| 6 | OTHER | 2015-03-06 |
| 7 | SUCCESS | 2015-03-07 |
| 8 | SUCCESS | 2015-03-07 |
| 9 | SUCCESS | 2015-03-07 |
| 10 | OTHER | 2015-03-08 |
| 11 | SUCCESS | 2015-03-08 |
| 12 | OTHER | 2015-03-08 |
| 13 | SUCCESS | 2015-03-09 |
| 14 | SUCCESS | 2015-03-09 |
| 15 | SUCCESS | 2015-03-09 |
| 16 | OTHER | 2015-03-10 |
| 17 | OTHER | 2015-03-10 |
| 18 | SUCCESS | 2015-03-10 |
| 19 | OTHER | 2015-03-11 |
+--------+-------------+------------+
eg output:
+---------------+-------------------------+
| count(statid) | auth_date |
+---------------+-------------------------+
| 0 | March, 06 2015 00:00:00 |
| 3 | March, 07 2015 00:00:00 |
| 1 | March, 08 2015 00:00:00 |
| 3 | March, 09 2015 00:00:00 |
+---------------+-------------------------+

It is not beautiful but hope it helps:
SELECT
date_auth,
count(stat_id) as typeSuccess,
device_type as typeName,
YEARWEEK(date_auth) as date
FROM
(
SELECT
DATE(DATE_ADD(NOW(), interval tmp.id day)) AS MyJoinDate
FROM (SELECT 1 as id
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
UNION ALL SELECT 13
UNION ALL SELECT 14
UNION ALL SELECT 15
UNION ALL SELECT 16
UNION ALL SELECT 17
UNION ALL SELECT 18
) AS tmp
) dateAll
LEFT JOIN auth_stat U on dateAll.MyJoinDate = U.date_auth
group by dateAll.MyJoinDate

I have tried adding the query as below. It stills returns me records that have the counts and not the dates with the count as zero.
SELECT COUNT(stat_id), dates.date_auth
FROM
( SELECT DISTINCT date_auth
FROM auth_stat
WHERE date_auth BETWEEN DATE_SUB(CURDATE(), INTERVAL 20 DAY) AND CURDATE()
) AS dates
LEFT JOIN auth_stat ON TRUE
AND auth_stat.date_auth = dates.date_auth
AND auth_stat.auth_result = 'SUCCESS'
GROUP BY dates.date_auth
ORDER BY dates.date_auth
Output result for the above query:
COUNT(stat_id) date_auth Ascending 1
1 2015-03-05 00:00:00
1 2015-03-06 00:00:00
11 2015-03-18 00:00:00

Related

How to count the number of first transactions of each user per day?

I have a table named transactions which contains all transactions. Something like this:
// transactions
+--------+-------------+---------+-------------+---------------------+
| id | business_id | user_id | amount | created_at |
+--------+-------------+---------+-------------+---------------------+
| 1 | 503 | 12 | 4500 | 2021-04-15 04:22:09 |
| 2 | 33 | 12 | 1200 | 2021-04-17 12:22:10 |
| 3 | 771 | 13 | 400 | 2021-04-18 13:02:18 |
| 4 | 86 | 14 | 7500 | 2021-04-18 16:07:12 |
| 5 | 772 | 13 | 3400 | 2021-04-23 07:11:04 |
| 6 | 652 | 14 | 900 | 2021-04-24 10:35:08 |
| 7 | 567 | 15 | 1000 | 2021-04-24 14:55:11 |
+--------+-------------+---------+-------------+---------------------+
I need to count the number of users that have had their first transaction per day. So here is the expected result:
// The expected result
+------+-------+-------+--------------------------+
| year | month | day | first_transactions_num |
+------+-------+-------+--------------------------+
| 2021 | 04 | 15 | 1 |
| 2021 | 04 | 18 | 2 |
| 2021 | 04 | 24 | 1 |
+------+-------+-------+--------------------------+
Any idea how can I do that?
Here's what I've tried:
SELECT year(created_at) year,
month(created_at) month,
day(created_at) day,
count(1) num
FROM transactions
GROUP BY year, month, day
But my query doesn't care about "the first transaction of each user".
You should aggregate on the results of this query:
SELECT MIN(created_at) created_at
FROM transactions
GROUP BY user_id
which returns the 1st transaction of each user.
So do it like this:
SELECT YEAR(created_at) year,
MONTH(created_at) month,
DAY(created_at) day,
COUNT(*) num
FROM (
SELECT MIN(created_at) created_at
FROM transactions
GROUP BY user_id
) t
GROUP BY year, month, day
Or better:
SELECT YEAR(created_at) year,
MONTH(created_at) month,
DAY(created_at) day,
COUNT(*) num
FROM (
SELECT DATE(MIN(created_at)) created_at
FROM transactions
GROUP BY user_id
) t
GROUP BY created_at
Or if your version of MySql is 8.0+ use COUNT() window function:
SELECT DISTINCT
YEAR(MIN(created_at)) year,
MONTH(MIN(created_at)) month,
DAY(MIN(created_at)) day,
COUNT(*) OVER (PARTITION BY DATE(MIN(created_at))) num
FROM transactions
GROUP BY user_id
See the demo.

How to get zero count for missing dates in mysql group by clause

I have a mysql table from which i need to find how many records created per day in last 30 days.
A simple query for that is like
select count(*) from table_name where date(created) > yyyymmdd group by date(created) order by date(created)
I don't require to select date here, just the counts.
So i expect 30 rows here.
But the problem here is if there are no records created on some day, it will not appear in the result and I'll have less than 30 rows.
Is there any other way to print zero (0) count for the dates where no records are created ?
current output :
+---------------+----------+
| date(created) | count(*) |
+---------------+----------+
| 2019-12-20 | 1504 |
| 2019-12-29 | 12 |
+---------------+----------+
Expected output :
+---------------+----------+
| date(created) | count(*) |
+---------------+----------+
| 2019-12-20 | 1504 |
| 2019-12-21 | 0 |
| 2019-12-22 | 0 |
| 2019-12-23 | 0 |
| 2019-12-24 | 0 |
| 2019-12-25 | 0 |
| 2019-12-26 | 0 |
| 2019-12-27 | 0 |
| 2019-12-28 | 0 |
| 2019-12-29 | 12 |
+---------------+----------+
you can use like this :
SET #date_min = '2019-12-20';
SET #date_max = '2019-12-29';
SELECT
date_generator.date as the_date,
IFNULL(COUNT(table_name.id), 0) as count
from (
select DATE_ADD(#date_min, INTERVAL (#i:=#i+1)-1 DAY) as `date`
from information_schema.columns,(SELECT #i:=0) gen_sub
where DATE_ADD(#date_min,INTERVAL #i DAY) BETWEEN #date_min AND #date_max
) date_generator
left join `table_name` on DATE(created) = date_generator.date
GROUP BY date;
so here I am creating a temporary table date_generator will dates in between of given date range and join to with your main table (transactions).
output as expected:
+---------------+----------+
| the_date | count |
+---------------+----------+
| 2019-12-20 | 1504 |
| 2019-12-21 | 0 |
| 2019-12-22 | 0 |
| 2019-12-23 | 0 |
| 2019-12-24 | 0 |
| 2019-12-25 | 0 |
| 2019-12-26 | 0 |
| 2019-12-27 | 0 |
| 2019-12-28 | 0 |
| 2019-12-29 | 12 |
+---------------+----------+
Test:
WITH RECURSIVE
cte AS ( SELECT #yyyymmdd + INTERVAL 1 DAY dateCreated
UNION ALL
SELECT dateCreated + INTERVAL 1 DAY
FROM cte
WHERE dateCreated < ( SELECT MAX(DATE(created))
FROM table_name ) )
SELECT COUNT(table_name.created)
FROM cte
JOIN table_name ON DATE(table_name.created) = cte.dateCreated
GROUP BY cte.dateCreated
ORDER BY cte.dateCreated
#yyyymmdd is a variable or placeholder where the value from the condition of your query (where date(created) > yyyymmdd) must be specified.

MySQL: multiple count in one row

I have next data:
mysql> select no,crt_date,tobilling_date,sent_to_client,dop_prov from assistfin limit 20;
+--------+---------------------+---------------------+----------------+------------+
| no | crt_date | tobilling_date | sent_to_client | dop_prov |
+--------+---------------------+---------------------+----------------+------------+
| 50.01 | 2014-02-05 10:28:10 | 2014-02-05 14:42:35 | 2014-04-16 | 2014-09-23 |
| 123.01 | 2014-02-05 19:17:36 | 2014-03-17 18:58:05 | 2014-04-10 | 2014-06-30 |
| 51.01 | 2014-02-06 00:09:32 | 2014-03-20 16:53:46 | 2014-04-10 | 2014-06-30 |
| 124.01 | 2014-02-06 15:29:08 | 2014-03-20 17:04:42 | 2014-04-10 | 2014-06-30 |
| 230.01 | 2014-02-07 22:01:11 | 2014-03-20 16:41:03 | 2014-04-10 | 2014-06-30 |
| 252.01 | 2014-02-08 02:52:33 | 2014-03-20 16:43:03 | 2014-04-10 | 2014-06-30 |
| 123.02 | 2014-02-08 03:00:52 | 2014-03-17 18:58:10 | 2014-04-10 | 2014-06-30 |
| 213.01 | 2014-02-08 04:01:35 | 2014-03-26 19:03:01 | 2014-04-10 | 2014-09-19 |
| 55.01 | 2014-02-08 21:04:45 | 2014-03-07 18:40:46 | NULL | 2014-06-26 |
| 126.01 | 2014-02-08 21:46:58 | 2014-09-02 18:39:36 | 2014-09-09 | 2014-09-26 |
| 284.01 | 2014-02-09 01:52:54 | 2014-06-11 19:11:06 | 2014-07-02 | 2014-07-21 |
| 261.01 | 2014-02-09 02:20:34 | 2014-03-17 20:57:39 | 2014-04-10 | 2014-06-30 |
| 318.01 | 2014-02-09 03:09:28 | 2014-03-17 20:44:25 | 2014-04-10 | 2014-06-30 |
| 225.01 | 2015-02-10 03:21:08 | 2014-03-20 16:57:56 | 2014-04-10 | 2014-06-30 |
| 248.01 | 2014-02-09 03:30:58 | 2014-03-18 18:02:21 | 2014-04-10 | 2014-06-30 |
| 178.01 | 2014-04-05 03:35:25 | 2014-03-21 17:10:12 | 2014-04-10 | 2014-06-30 |
| 184.01 | 2014-04-08 04:01:13 | 2015-03-20 16:38:02 | 2015-04-10 | 2015-06-30 |
| 320.01 | 2014-04-08 05:57:23 | 2015-03-17 20:49:19 | 2015-04-10 | 2015-06-30 |
| 230.02 | 2015-05-08 06:18:15 | 2016-03-20 16:41:08 | 2016-04-10 | 2016-06-06 |
| 325.01 | 2014-05-09 06:23:50 | 2015-03-17 20:42:04 | 2015-04-10 | 2015-06-30 |
+--------+---------------------+---------------------+----------------+------------+
Need to get next data:
+---------+---------+--------+-----------+---------+
| year | Created | Passed | To client | To prov |
+---------+---------+--------+-----------+---------+
| 2016-01 | 1901 | 1879 | 1873 | 1743 |
| 2016-02 | 2192 | 2169 | 2114 | 1912 |
| 2016-03 | 2693 | 2639 | 2539 | 2309 |
| 2016-04 | 2634 | 2574 | 2273 | 1976 |
| 2016-05 | 2593 | 2497 | 1109 | 949 |
| 2016-06 | 471 | 449 | 2 | 78 |
+---------+---------+--------+-----------+---------+
Where year like DATE_FORMAT(curdate(), '%Y-%m'), next column Count(assistfin.crt_date) as Created.
The problem is that crt_date can be like 2015%, but sent_to_client or dop_prov can be like 2016%.
How to make correct query?
Ok sorry this is so long and messy and also I couldnt do it using unions as I so arrogantly posted in the comments, also have to reference MySQL: Is it possible to 'fill' a SELECT with values without a table? that gave me the list of months. You could rewrite it so you left join all the tables to crt_date, but then it wont show a month when nothing was created, hence the generated months table. The original query had a limit 120 in the months, but I have replaced it with a datetime > '2014' for you to change with your earliest date.
Try this and see how quickly it runs for you.
select Months.yearmonth, created, passed, to_client, to_prov
from
(SELECT date_format(datetime,'%Y-%m') as yearmonth
FROM (
select (curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) MONTH) as datetime
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
) AS t
where datetime > '2014' -- enter your earliest year here
ORDER BY datetime ASC) Months left join
(select date_format(crt_date,'%Y-%m') as yearmonth, count(no) as "created" from assistfin group by yearmonth) created on Months.yearmonth=created.yearmonth
left join
(select date_format(tobilling_date,'%Y-%m') as yearmonth, count(no) as "passed" from assistfin group by yearmonth) passed on Months.yearmonth=passed.yearmonth
left join
(select date_format(sent_to_client,'%Y-%m') as yearmonth, count(no) as "to_client" from assistfin group by yearmonth) to_client on Months.yearmonth=to_client.yearmonth
left join
(select date_format(dop_prov,'%Y-%m') as yearmonth, count(no) as "to_prov" from assistfin group by yearmonth) to_prov on Months.yearmonth=to_prov.yearmonth
where
group by yearmonth;
Use group by and date_forma in where
select date_format(crt_date, '%Y-%m') as year, count(sent_to_client ), count(dop_pprov)
from assistfin
where date_format(crt_date, '%Y-%m') = date_format(now(), '%Y-%m')
group by year
for the year you can
select date_format(crt_date, '%Y-%m') as year, count(sent_to_client ), count(dop_pprov)
from assistfin
where date_format(crt_date, '%Y') = date_format(now(), '%Y')
group by year
OR for A Range OF yearS you can
select date_format(crt_date, '%Y-%m') as year, count(sent_to_client ), count(dop_pprov)
from assistfin
where date_format(crt_date, '%Y')
BETWEEN(date_format(now(),'%Y')-2) and date_format(now(), '%Y')
group by year

get all dates in the current month

i have table
userID | date | time
===================
1 | 2015-02-08 | 06:32
1 | 2015-02-08 | 05:36
1 | 2015-02-08 | 17:43
1 | 2015-02-08 | 18:00
1 | 2015-02-09 | 06:36
1 | 2015-02-09 | 15:43
1 | 2015-02-09 | 19:00
1 | 2015-02-10 | 05:36
1 | 2015-02-10 | 17:43
1 | 2015-02-10 | 18:00
2 | 2015-02-08 | 06:32
2 | 2015-02-08 | 05:36
2 | 2015-02-08 | 17:43
2 | 2015-02-08 | 18:00
2 | 2015-02-09 | 06:36
2 | 2015-02-09 | 15:43
2 | 2015-02-09 | 19:00
2 | 2015-02-10 | 05:36
2 | 2015-02-10 | 17:43
2 | 2015-02-10 | 18:00
But i want the number of records returned to be exactly the same as the number of days of the current month and get min time for in and max time for the out. if the current month has 28 days and only had two records it should bring:
userID | date | in | out
========================
1 | 2015-02-01 | |
1 | 2015-02-02 | |
1 | 2015-02-03 | |
1 | 2015-02-04 | |
1 | 2015-02-05 | |
1 | 2015-02-06 | |
1 | 2015-02-07 | |
1 | 2015-02-08 | 06:32 | 18:00
1 | 2015-02-09 | 06:36 | 19:00
1 | 2015-02-10 | 05:36 | 18:00
1 | 2015-02-11 | |
1 | 2015-02-12 | |
1 | 2015-02-13 | |
1 | 2015-02-14 | |
1 | 2015-02-15 | |
1 | 2015-02-16 | |
1 | 2015-02-17 | |
1 | 2015-02-18 | |
1 | 2015-02-19 | |
1 | 2015-02-20 | |
1 | 2015-02-21 | |
1 | 2015-02-22 | |
1 | 2015-02-23 | |
1 | 2015-02-24 | |
1 | 2015-02-25 | |
1 | 2015-02-26 | |
1 | 2015-02-27 | |
1 | 2015-02-28 | |
How can i modify my query to achieve the above result?
this is my query:
$sql = "SELECT
colUserID,
colDate,
if(min(colJam) < '12:00:00',min(colJam), '') as in,
if(max(colJam) > '12:00:00',max(colJam), '') as out
FROM tb_kehadiran
WHERE colDate > DATE_ADD(MAKEDATE($tahun, 31),
INTERVAL($bulan-2) MONTH)
AND
colDate < DATE_ADD(MAKEDATE($tahun, 1),
INTERVAL($bulan) MONTH)
AND
colUserID = $user_id
GROUP BY colUserID,colDate";
I had to think about this one. But probably the simpliest answer so far:
WITH AllMonthDays as (
SELECT n = 1
UNION ALL
SELECT n + 1 FROM AllMonthDays WHERE n + 1 <= DAY(EOMONTH(GETDATE()))
)
SELECT
DISTINCT datefromparts(YEAR(GETDATE()), MONTH(GETDATE()), n) As dates
, MIN(d.time) as 'In'
, MAX(d.time) as 'Out'
FROM AllMonthDays as A
LEFT OUTER JOIN
table as d on
DAY(d.date) = A.n
GROUP BY n,(d.date);
--- Test and tried in this environment: ---
use Example;
CREATE TABLE demo (
ID int identity(1,1)
,date date
,time time
);
INSERT INTO demo (date, time) VALUES
('2015-12-08', '06:32'),
('2015-12-08', '05:36'),
('2015-12-08', '17:43'),
('2015-12-08', '18:00'),
('2015-12-09', '06:36'),
('2015-12-09', '15:43'),
('2015-12-09', '19:00'),
('2015-12-10', '05:36'),
('2015-12-10', '17:43'),
('2015-12-10', '18:00')
;
WITH AllMonthDays as (
SELECT n = 1
UNION ALL
SELECT n + 1 FROM AllMonthDays WHERE n + 1 <= DAY(EOMONTH(GETDATE()))
)
SELECT
DISTINCT datefromparts(YEAR(GETDATE()), MONTH(GETDATE()), n) As dates
, MIN(d.time) as 'In'
, MAX(d.time) as 'Out'
FROM AllMonthDays as A
LEFT OUTER JOIN
demo as d on
DAY(d.date) = A.n
GROUP BY n,(d.date);
DROP table demo;
The way I've approached this problem in the past is to have a date table that is pre-populated for some years in the future.
You could create such a table, possibly defining columns for year, month and date, with indexes on year and month.
You can then use this table with a JOIN on your data to ensure that all dates are present in your results.
You need three things:
A list of dates.
A left join
Aggregation
So:
select d.dte, min(t.time), max(t.time)
from (select date('2015-02-01') as dte union all
select date('2015-02-02') union all
. .
select date('2015-02-28')
) d left join
t
on d.dte = t.date
group by d.dte
order by d.dte;
Try this
set #is_first_date = 0;
set #temp_start_date = date('2015-02-01');
set #temp_end_date = date('2015-02-28');
select my_dates.date,your_table_name.user_id, MIN(your_table_name.time), MAX(your_table_name.time) from
( select if(#is_first_date , #temp_start_date := DATE_ADD(#temp_start_date, interval 1 day), #temp_start_date) as date,#is_first_date:=#is_first_date+1 as start_date from information_schema.COLUMNS
where #temp_start_date < #temp_end_date limit 0, 31
) my_dates left join your_table_name on
my_dates.date = your_table_name.date
group by my_dates.date
Try This query
SELECT `date`, MIN(`time`) as `IN`, MAX('time') AS `OUT`
FROM `table_name` WHERE month(current_date) = month(`date`)
GROUP BY `date`;

Confuse query add date not in table for mysql

excuse me,
i will add date if that date not in table on mysql
example i have table
ID | name | date | clock in | clock out
---------------------------------------------------------------
1001 | A | 2013-09-18 | 09:40 | 17:15
1001 | A | 2013-09-20 | 08:20 | 17:35
1001 | A | 2013-09-21 | 08:40 | 17:40
1001 | A | 2013-09-23 | 08:10 | 17:50
so, how to add date in to no table and set clock in and clock out set null
example
ID | name | date | clock in | clock out
---------------------------------------------------------------
1001 | A | 2013-09-18 | 09:40 | 17:15
1001 | A | 2013-09-19 | null | null
1001 | A | 2013-09-20 | 08:40 | 17:40
1001 | A | 2013-09-21 | 08:10 | 17:50
1001 | A | 2013-09-22 | null | null
1001 | A | 2013-09-23 | 08:10 | 17:50
thanks
This is what you need if you're still interested:
SELECT
COALESCE(id,1001) id,
COALESCE(name,'A') name,
fixed_days.fixed_date,
clockin,clockout
FROM t
RIGHT JOIN
(SELECT CURDATE() as fixed_date
UNION ALL SELECT CURDATE() - INTERVAL 1 day
UNION ALL SELECT CURDATE() - INTERVAL 2 day
UNION ALL SELECT CURDATE() - INTERVAL 3 day
UNION ALL SELECT CURDATE() - INTERVAL 4 day
UNION ALL SELECT CURDATE() - INTERVAL 5 day
UNION ALL SELECT CURDATE() - INTERVAL 6 day) AS fixed_days
ON t.record_date = fixed_days.fixed_date
WHERE fixed_days.fixed_date <= (select max(record_date) from t);
SQL Fiddle..