我有一张表,其中有两列:
MARKS
CREAT_TS
我想要在两个日期范围之间的日平均分数(例如startDate& endDate)
我做了以下查询:
select SUM(MARKS)/ COUNT(date(CREAT_TS)) AS DAILY_AVG_MARKS,
date(CREAT_TS) AS DATE
from TABLENAME
group by date(CREAT_TS)
使用此查询,只有数据库中有一行日期才能获得每日平均值。但我的要求是,即使没有行,我也希望在该日期显示0。 我的意思是如果(startDate,endDate)
之间有X天,我希望查询返回X行任何人都可以帮助我。 :(
答案 0 :(得分:4)
您需要创建一组可以添加到日期的整数。以下内容将为您提供一个想法:
select thedate, avg(Marks) as DAILY_AVG_MARKS
from (select startdate+ interval num day as thedate
from (select d1.d + 10 * d2.d + 100*d3.d as num
from (select 0 as d union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9
) d1 cross join
(select 0 as d union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9
) d2 cross join
(select 0 as d union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9
) d3
) n cross join
(select XXX as startdate, YYY as enddate) const
where startdate + num <= enddate
) left outer join
tablename t
on date(CREAT_TS) = thedate
group by thedate
所有复杂情况都是为报告创建一组连续日期。如果您有一个numbers
表或calendar
表,那么SQL看起来会简单得多。
这是如何工作的?第一个大子查询有两个部分。第一个只是通过交叉连接数字0-9并进行一些算术来生成从0到999的数字。第二个将日期加到startdate
和enddate
两个日期 - 您需要为XXX和YYY输入正确的值。使用此表,您可以获得两个值之间的所有日期。如果您需要超过999天,只需添加另一个交叉联接。
这是左边连接到你的数据表。结果是所有日期都显示在组中。
在报告方面,在表示层中执行此操作有利有弊。基本上,在SQL中执行它的优点是报表层更简单。在报告层中执行此操作的优点是SQL更简单。外人很难做出判断。
我的建议是创建一个数字表,你可以在这样的报告中使用它。然后查询看起来会更简单,您不必更改报告层。