我试图从3月1日到3日的日期获得葡萄计数。
你会注意到3月2日 - 没有插入葡萄..
我可以在3月1日,2日和3日显示查询,但显示3月2日的0计数
在上图中,只显示有葡萄的日期..
这是mySQL查询
SELECT `fruitDate` , `fruitName` , COUNT( * )
FROM `tbl_fruits`
WHERE `fruitName` = "Grapes"
GROUP BY `fruitDate
更新2:
使用此查询:
SELECT f.fruitDate, f.fruitName, f1.count FROM tbl_fruits f
LEFT JOIN (SELECT fruitDate, COUNT(*) as count from tbl_fruits d WHERE d.fruitName='Grapes' GROUP BY d.fruitDate) as f1 ON (f.fruitDate = f1.fruitDate)
GROUP BY f.fruitDate
我得到了这个结果..但它显示了不同的水果......我的查询有问题吗?
答案 0 :(得分:6)
3月2日是您的表中不存在的数据,它会从中选择什么?也就是说,由于count()
计算每个日期“Grapes”的存在的行数,并且3月2日“Grapes”没有行,{{1}没有数据可以统计,没有任何东西可以告诉数据库插入缺少的日期。
为了解决这个问题,我过去所做的是创建一个单独的表Calendar,它包含给定范围的每个日期的行。然后,您可以count()
到此表,以确保为每个日期选择一行。它可能看起来像这样:
JOIN
请注意,SELECT cal.`Date`, 'Grapes' as `fruitName`, COUNT(f.`fruitName`)
FROM `tbl_Calendar` cal
LEFT JOIN `tbl_fruits` f ON cal.`Date` = f.`fruitDate`
WHERE `fruitName` = "Grapes"
AND '2012-03-01' <= cal.`Date` AND cal.`Date` <= '2012-03-03'
GROUP BY cal.`Date`
永远不会返回0,因为每个日期都会返回一行。要获得0,请计算在找到0行时为NULL的字段,在这种情况下,我计算count(*)
Calendar表可以像
一样简单fruitName
从选定的开始日期到结束日期,您将使用简单的PHP循环填充。您可能会发现添加其他列以缓存诸如星期几或假期等内容的好处,但此任务不需要这样做。
修改强>
在你的编辑中,你似乎试图加入你的水果表来获取日期,但你的查询中有一些错误,而是尝试用类似的子查询代替我的Calendar表:
CREATE TABLE tbl_Calendar (
`Date` date NOT NULL PRIMARY KEY
)
但请注意,虽然这将填补其他一些水果没有遗漏的葡萄缺失日期,但它不会填写所有水果缺少的日期。
答案 1 :(得分:2)
请记住,创建一个不需要创建表的日期范围有一个动态(有点难看)的解决方案:
select aDate from (
select @maxDate - interval (a.a+(10*b.a)+(100*c.a)+(1000*d.a)) day aDate 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) a, /*10 day range*/
(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) b, /*100 day range*/
(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) c, /*1000 day range*/
(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) d, /*10000 day range*/
(select @minDate := '2001-01-01', @maxDate := '2002-02-02') e
) f
where aDate between @minDate and @maxDate
根据日期范围的长度,您可以通过删除表格(d,c,b和a)并从中删除它们来减少动态生成结果的数量(10000天意味着超过27年的记录,每个代表一天)上层公式。通过设置@minDate
和@maxDate
变量,您可以指定要过滤结果的日期。
修改强>
我看到你还在寻找解决方案。试试这个:
select c.date, f.fruitName, count(f.fruitName = 'Grapes')
from tbl_calendar c
left join tbl_fruits f
on c.date = f.fruitDate and f.fruitName = 'Grapes'
group by c.date, f.fruitName
如果您还想从创建的表中过滤额外日期,请使用以下查询:
select c.date, f.fruitName, count(f.fruitName = 'Grapes')
from tbl_calendar c
left join tbl_fruits f
on c.date = f.fruitDate and f.fruitName = 'Grapes'
group by c.date, f.fruitName
having c.date between
(select min(fruitDate) from tbl_fruits) and
(select max(fruitDate) from tbl_fruits)