2009-10-27 75 views
1

我在MySQL中,下表...SQL計數行

CREATE TABLE `visits` (
    `id` int(10) unsigned NOT NULL auto_increment, 
    `visit` datetime NOT NULL default '0000-00-00 00:00:00', 
    `bulletin` int(11) NOT NULL default '0', 
    PRIMARY KEY (`id`) 
) 

其中,「遊」是一個訪問發生的時間,而「公告」是當時請求的文章。

我想知道什麼時候很受我的用戶,所以我有以下查詢......

SELECT 
    count(*) as c, 
    Date_format (visit, '%l%p, %e %b %Y') as e 
FROM 
    `visits` 
WHERE 1 
AND 
    date(visit) > date(now() - interval 2 day) 
group by e 
order by visit desc 

它返回......

c e 
4 12PM, 27 Oct 2009 
9 11AM, 27 Oct 2009 
5 10AM, 27 Oct 2009 
2 9AM, 27 Oct 2009 
3 4PM, 26 Oct 2009 
6 3PM, 26 Oct 2009 
16 2PM, 26 Oct 2009 

到目前爲止好。

但是,如何讓查詢返回「0」計數和缺少時間的時間?例如,我想結果看起來像...

c e 
4 12PM, 27 Oct 2009 
9 11AM, 27 Oct 2009 
5 10AM, 27 Oct 2009 
2 9AM, 27 Oct 2009 
0 8AM, 27 Oct 2009 
0 7AM, 27 Oct 2009 
0 6AM, 27 Oct 2009 
0 5AM, 27 Oct 2009 
0 4AM, 27 Oct 2009 
0 3AM, 27 Oct 2009 
0 2AM, 27 Oct 2009 
0 1AM, 27 Oct 2009 
0 12am, 27 Oct 2009 
0 11pm, 26 Oct 2009 
0 10pm, 26 Oct 2009 
0 9pm, 26 Oct 2009 
0 8pm, 26 Oct 2009 
0 7pm, 26 Oct 2009  
0 6pm, 26 Oct 2009 
0 5pm, 26 Oct 2009 
3 4PM, 26 Oct 2009 
6 3PM, 26 Oct 2009 
16 2PM, 26 Oct 2009 

我可以在輸出代碼時,我打印結果做傻事,但我想查詢爲我提供了,如果可能的話。

+0

http://stackoverflow.com/questions/434571/mysql-query-getting-missing-records-when -using-group-by –

回答

1
  1. 創建數字表:

    CREATE TABLE `NUMBERS` (
        `num` int(11) NOT NULL auto_increment, 
        PRIMARY KEY (`num`) 
    ) 
    
  2. 填充表:

    INSERT INTO NUMBERS VALUES (NULL) 
    

    根據你的榜樣,你需要運行該語句〜36倍。

  3. 使用以下命令:

    SELECT IFNULL(vd.num_visits, 0), 
          DATE_FORMAT(s.gdate, '%l%p, %e %b %Y') 
        FROM (SELECT DATE_ADD(@min_date, INTERVAL n.num-1 HOUR) 'gdate' 
          FROM NUMBERS n 
          WHERE DATE_ADD(@min_date, INTERVAL n.num-1 HOUR) <= @max_date) s 
    LEFT JOIN (SELECT v.visits, 
            COUNT(*) 'num_visits' 
          FROM visits v 
         GROUP BY v.visits) vd ON vd.visits = s.gdate 
    ORDER BY s.gdate DESC 
    

的數字表是一個老把戲,使用時你不能遞歸生成值的列表。

如果您想根據最小/最大的VISITS表,使用使用方法:

FROM (SELECT DATE_ADD(@min_date, INTERVAL n.num-1 HOUR) 'gdate' 
     FROM NUMBERS n 
     JOIN (SELECT MIN(t.visits) 'minv', 
        MAX(t.visits) 'maxv' 
       FROM visits t) t 
     WHERE DATE_ADD(t.minv, INTERVAL n.num-1 HOUR) <= t.maxv) s 
+0

這或多或少是我最終做的,雖然我的代碼不像這樣全面。 感謝大家的這種及時迴應:) – nedlud

0

您可能必須在查詢中創建假日期才能完成此操作...只需在一天中的24小時內填充數組,然後只更改查詢行循環中的0值。

2

您應該從生成的數據集中選擇所有日期&次,左側加入表中的「訪問次數」。我不知道MySQL的非常好,所以我不能給你如何產生設定日期和時間的例子,但類似:

SELECT 
    count(*) as c, 
    Date_format (d.DateTime, '%l%p, %e %b %Y') as e 
FROM 
    GetDateSetFunction() d 
LEFT JOIN 
    `visits` v 
    ON Date_format(d.DateTime, '%l%p, %e %b %Y') = Date_format (v.visit, '%l%p, %e %b %Y') 
WHERE 1 
AND 
    date(d) > date(now() - interval 2 day) 
group by e 
order by d.DateTime desc 
0

你應該能夠爲所有的做工會總和。

select count(*) as c, Date_format (visit, '%l%p, %e %b %Y') as e 
from table where 
date(visit) > date(now() - interval 2 day) 
and date(visit) < date(now() - interval 2 day + 1 hour) 
group by e 
union 
select count(*) as c, Date_format (visit, '%l%p, %e %b %Y') as e 
from table where 
date(visit) > date(now() - interval 2 day + 1 hour) 
and date(visit) < date(now() - interval 2 day + 2 hour) 
group by e 
... #etc 
union 
select count(*) as c, Date_format (visit, '%l%p, %e %b %Y') as e 
from table where 
date(visit) > date(now() - interval 2 day + 47 hour) 
and date(visit) < date(now() - interval 2 day + 48 hour) 
group by e; 

這個想法是你分別抓住每個小時,將它們分組在一起。當某個特定時間沒有結果時,您仍然得到0計數。

我不是很熟悉mysql的語法細節,所以我把它們放在一起作爲psuedo-sql。我已經從代碼中複製了大多數語法,但不知道我是否漏掉了一些東西。我沒有測試過這個代碼。