0

我有一个表,其中有两列:

分数

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 行

谁能帮我。:(

4

1 回答 1

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 更简单。外人很难做出这样的判断。

My suggestion would be to create a numbers table that you can just use in reports like this. Then the query will look simpler and you won't have to change the reporting layer.

于 2013-03-04T14:49:58.780 回答