Reputation: 2562
How can i make this query to return a row with 0 value if there is no value for each date
SELECT COUNT(id) FROM `panel_messages` WHERE `sent_by` = 'root'
AND `send_date` IN ("1395-4-25","1395-4-24","1395-4-23","1395-4-22","1395-4-21","1395-4-20","1395-4-19")
GROUP BY `send_date`
ORDER BY `send_date` DESC
My expected result is 7 rows like this :
| row1 |
| row2 |
| row3 |
| row4 |
| row5 |
| row6 |
| row7 |
and if there is no result for one of the rows i want it to be 0 which is default value :
| 2 |
| 0 |
| 0 |
| 2 |
| 0 |
| 3 |
| 1 |
But right now i just get 4 rows because if there is no result my query doesn't return anything :
| 2 |
| 2 |
| 3 |
| 1 |
SQL fiddle : http://sqlfiddle.com/#!9/a07486/3
Upvotes: 1
Views: 3343
Reputation: 14721
onother answer what you are trying to do is impossible without the union :
but you can try some think else create a temporary table that contain your date
create Table temporary (
send_date date
);
insert INTO temporay("1395-4-25"),("1395-4-24"),("1395-4-23"),("1395-4-22"),("1395-4-21"),("1395-4-20"),("1395-4-19")
than do select with rigth join between your table and this one now you will have record for the date that don't have send_by
panel_messages.sent_by | panel_messages.send_date | temporary.send_date
root "1395-4-25" "1395-4-25"
root "1395-4-25" "1395-4-25"
null null "1395-4-24"
null null "1395-4-23"
root "1395-4-19" "1395-4-19"
.
.
.
now you count how much message in every day all i did is create a result that can return what you need :
Try this select after you create the temporary table
SELECT temporary.send_date, count(sender_by)
from panel_messages RIGTH JOIN temporary ON (temporary.send_date = panel_messages.send_date)
where
panel_messages.sent_by like 'root'
group by temporary.send_date
ORDER BY send_date DESC;
Upvotes: 1
Reputation: 13519
Please give it a try:
SELECT
COALESCE(YT.total,t.total) AS cnt
FROM
(SELECT 0 AS total) t
LEFT JOIN
(
SELECT
COUNT(id) AS total
FROM `panel_messages`
WHERE `sent_by` = 'root'
AND `send_date` IN ("1395-4-25","1395-4-24","1395-4-23","1395-4-22","1395-4-21","1395-4-20","1395-4-19")
GROUP BY `send_date`
ORDER BY `send_date` DESC
) YT
ON 1=1;
Note:
A dummy row has been created with value 0
.
Later doing a LEFT JOIN
between this dummy table and your query
And finally using COALESCE
you can achieve the default count 0
if your main query doesn't return anything.
EDIT:
Query:
SELECT
COALESCE(YT.count,0) AS count
FROM
(
SELECT ADDDATE('1395-01-01', INTERVAL @i:=@i+1 DAY) AS DAY
FROM (
SELECT a.a
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
JOIN (SELECT @i := -1) r1
) dateTable
LEFT JOIN
(
SELECT
send_date,
COUNT(id) AS count
FROM
`panel_messages`
WHERE
`sent_by` = 'root'
AND `send_date` IN (
"1395-4-25",
"1395-4-24",
"1395-4-23",
"1395-4-20"
)
GROUP BY
`send_date`
ORDER BY
`send_date` DESC
) AS YT
ON dateTable.DAY = YT.send_date
WHERE dateTable.DAY IN ('1395-04-25','1395-04-24','1395-04-23','1395-04-20');
In order to get zero count for the dates which don't exist you need to create a temporary table where all the dates (under a certain range) reside.
Then making a left join between the date field of this temporary table and send_date
field of your table would do the job done almost.
Finally you need to use COALESCE
to get 0
if the count
is NULL
.
Upvotes: 2
Reputation: 14721
try this :
SELECT sent_by ,"1395-4-25" as `SEND DATE`,COUNT(*) FROM `panel_messages` WHERE `sent_by` = 'root' AND `send_date` = "1395-4-25"
union
SELECT sent_by ,"1395-4-24" as `SEND DATE`,COUNT(*) FROM `panel_messages` WHERE `sent_by` = 'root' AND `send_date` = "1395-4-24"
union
SELECT sent_by ,"1395-4-23" as `SEND DATE`,COUNT(*) FROM `panel_messages` WHERE `sent_by` = 'root' AND `send_date` = "1395-4-23"
ORDER BY `SEND DATE` DESC
in this case when date is not found the count(*) return 0; but in the first return null add the 4 select statement and it will return 7 rows now it work but it can be better if i found onother solution i'm going back here
Upvotes: 1