2016-07-15 58 views
1

我怎样才能使这个查询返回0值的行,如果有对于每一日期如何让查询返回0,而不是空集,如果没有结果

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 

我期望的结果是没有价值7行是这样的:

| row1 | 

| row2 | 

| row3 | 

| row4 | 

| row5 | 

| row6 | 

| row7 | 

和如果没有结果对于i希望它是0的行中的一个是默认值:

| 2 | 

| 0 | 

| 0 | 

| 2 | 

| 0 | 

| 3 | 

| 1 | 

但是现在我只拿到4行,因为如果没有结果我的查询不返回任何内容:

| 2 | 

| 2 | 

| 3 | 

| 1 | 

SQL小提琴:http://sqlfiddle.com/#!9/a07486/3

+0

你是什么当count(id)为0时,你想要返回null吗? – Cherif

回答

1

试试这个:

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 
在这种情况下

时的日期没有找到COUNT(*)返回0;但在第一个返回null添加4选择语句,它会返回7行现在它的工作,但它可以更好,如果我发现onother解决方案,我要回到这里

+0

我仍然得到4行。如果其中一个日期没有结果,则查询返回空集。例如,此查询返回空结果,但希望它返回0:SELECT COUNT(id)FROM'panel_messages' WHERE'sent_by' ='root' AND'send_date' IN(“1395-4-25”) GROUP BY' send_date' ORDER BY'send_date' DESC – Armin

+0

ahh is see the problem now now let it think about it – Cherif

+0

我编辑我的答案这应该回答你的问题 – Cherif

1

请试一试:

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; 

注:

已创建一个虚拟行,其值为0

后来做这个虚表之间的LEFT JOINquery

,最后用COALESCE可以实现默认计数0如果你的主查询不返回任何东西。

编辑:

查询:

SELECT 
COALESCE(YT.count,0) AS count 
FROM 
(
    SELECT ADDDATE('1395-01-01', INTERVAL @i:[email protected]+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'); 

为了获得零计数不存在,您需要创建一个临时表的日期,所有的时间(下一定范围)居住。

然后在该临时表的日期字段和send_date字段之间进行左连接,可以完成几乎完成的工作。

如果countNULL,最后您需要使用COALESCE来得到0

WORKING DEMO

+0

它的工作原理,但如果子查询返回空集(没有结果),它不返回0 – Armin

+0

事实上,你不需要在'count'上使用'IFNULL'。如果你的结果集是空的,那么你将不会得到任何行。当结果集为空时,你想显示默认值吗? – 1000111

+0

是这就是我想要的,我想默认值为0 – Armin

1

其他答案你想要做什么是不可能的没有工会:

,但你可以尝试一些想象还有 创建包含您的日期

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") 

比确实与分辩选择你的桌子,这一个之间加入一个临时表,现在你将有备案日期没有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" 
. 
. 
. 

现在你在每一天算多少消息,我所做的就是创建一个结果,可以返回你所需要的:

试试这个选择您创建临时表后

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; 
+0

试试这个解决方案我did'nt你union这里没有办法在mysql中创建一个值列表中的表或从值列表中创建一个选择我们必须创建一个临时表来插入它的值比加入 – Cherif

+0

告诉我,如果我没有工作,因为我测试它,它工作 – Cherif