如何在单个GROUP BY DAY(date_field)SQL查询中包含空行?

时间:2009-02-26 23:39:54

标签: sql sql-server date group-by

我正在使用MS SQL Server,但欢迎来自其他数据库的比较解决方案。

这是我查询的基本形式。它返回'incidentsm1'表中每天的调用次数:

SELECT 
  COUNT(*) AS "Calls",
  MAX(open_time),
  open_day
FROM 
  (
SELECT
 incident_id,
 opened_by,
 open_time - (9.0/24) AS open_time,
 DATEPART(dd, (open_time-(9.0/24))) AS open_day
   FROM incidentsm1 
   WHERE 
 DATEDIFF(DAY, open_time-(9.0/24), GETDATE())< 7

  ) inc1
GROUP BY open_day

此数据用于绘制条形图,但如果在一周中的某一天没有调用,则没有结果行,因此没有条形,并且用户就像“为什么图表只有六天,从周六到周一跳过?“

不知怎的,我需要UNION ALL每天都有一行空白或类似的东西,但我无法弄明白。

我受限于我可以用一个SQL语句做什么,而且我只能访问,所以我无法创建临时表或任何东西。

4 个答案:

答案 0 :(得分:7)

这样的事情怎么样?

SELECT 
  COUNT(incident_id) AS "Calls",
  MAX(open_time),
  days.open_day
FROM
(
  select datepart(dd,dateadd(day,-6,getdate())) as open_day union
  select datepart(dd,dateadd(day,-5,getdate())) as open_day union
  select datepart(dd,dateadd(day,-4,getdate())) as open_day union
  select datepart(dd,dateadd(day,-3,getdate())) as open_day union
  select datepart(dd,dateadd(day,-2,getdate())) as open_day union
  select datepart(dd,dateadd(day,-1,getdate())) as open_day union
  select datepart(dd,dateadd(day, 0,getdate())) as open_day 
) days
left join 
(
 SELECT
   incident_id,
   opened_by,
   open_time - (9.0/24) AS open_time,
   DATEPART(dd, (open_time-(9.0/24))) AS open_day
 FROM incidentsm1 
 WHERE DATEDIFF(DAY, open_time-(9.0/24), GETDATE()) < 7
) inc1 ON days.open_day = incidents.open_day
GROUP BY days.open_day

我只在简化的表架构上测试过它,但我认为它应该可行。你可能需要修补dateadd的东西......

答案 1 :(得分:0)

您可以创建一个包含所需日期的表变量,然后RIGHT JOIN到它上面吗?例如,

DECLARE @dateTable TABLE ([date] SMALLDATETIME)

INSERT INTO @dateTable
VALUES('26 FEB 2009')
INSERT INTO @dateTable
VALUES('27 FEB 2009')
-- etc

SELECT 
  COUNT(*) AS "Calls",
  MAX(open_time),
  open_day
FROM 
  (
SELECT
 incident_id,
 opened_by,
 open_time - (9.0/24) AS open_time,
 DATEPART(dd, (open_time-(9.0/24))) AS open_day
   FROM incidentsm1
   RIGHT JOIN @dateTable dates
   ON incidentsm1.open_day = dates.date
   WHERE 
 DATEDIFF(DAY, open_time-(9.0/24), GETDATE())< 7

  ) inc1
GROUP BY open_day

然而,更理想的情况是拥有一个日期为

的表对象

答案 2 :(得分:0)

我建议使用date table。使用现有的日期表,您可以对日期表执行RIGHT OUTER JOIN以带来遗失的日期。

答案 3 :(得分:0)

您可以在查询中创建一组日期吗?有点像:

SELECT COUNT(*) AS Calls, ...
    FROM incidentsm1 RIGHT OUTER JOIN
         (SELECT date_values
            FROM TABLE(('27 Feb 2009'), ('28 Feb 2009'), ('1 Mar 2009'),
                       ('2 Mar 2009'), ('3 Mar 2009'), ('4 Mar 2009'),
                       ('5 Mar 2009')) AS date_list
         )
         ON ...

这是受到Informix和DB2符号的混合的启发,并且几乎可以保证在语法上都不正确。基本上,在DBMS中有一种方法可以动态创建文字表。一种可能性 - 丑陋但几乎不可行 - 将是从“双重”或某些表格表达式中选择的7路UNION日期文字,它保证一行(在Informix术语中,SELECT MDY(2,28,2009) FROM "informix".systables WHERE tabid = 1 UNION ...)。