2016-07-15 103 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