我在MySQL中有以下表格......
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 :(得分: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
答案 1 :(得分:1)
创建一个数字表:
CREATE TABLE `NUMBERS` (
`num` int(11) NOT NULL auto_increment,
PRIMARY KEY (`num`)
)
填充表格:
INSERT INTO NUMBERS VALUES (NULL)
根据您的示例,您需要运行语句~36次。
使用以下内容:
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
答案 2 :(得分:0)
您可能必须在查询中创建假日期才能完成此操作...只需使用一天中的24小时填充数组,然后仅更改查询行循环中的0值。
答案 3 :(得分: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。我从你的代码中复制了大部分语法,但不知道我是否错过了什么。我还没有测试过这段代码。