简体   繁体   English

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

[英]How do I include empty rows in a single GROUP BY DAY(date_field) SQL query?

I'm using MS SQL Server but welcome comparitive solutions from other databases. 我正在使用MS SQL Server,但欢迎来自其他数据库的比较解决方案。

This is the basic form of my query. 这是我查询的基本形式。 It returns the number of calls per day from the 'incidentsm1' table: 它返回'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

This data is used to draw a bar graph, but if there were no calls on a given day of the week, there is no result row and thus no bar, and the user is like, "why does the graph only have six days and skip from Saturday to Monday?" 此数据用于绘制条形图,但如果在一周中的某一天没有调用,则没有结果行,因此没有条形,并且用户就像是,“为什么图表只有六天,从周六到周一跳过?“

Somehow I need to UNION ALL with a blank row from each day or something like that, but I can't figure it out. 不知怎的,我需要UNION ALL每天都有一个空白行或类似的东西,但我无法弄明白。

I am constrained to what I can do with one SQL statement and I have readonly access so I can't create a temporary table or anything. 我受限于我可以用一个SQL语句做什么,我只读访问,所以我不能创建一个临时表或任何东西。

How about something like this? 这样的事怎么样?

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

I've only tested it on a simplified table schema, but I think it should work. 我只在一个简化的表模式上测试它,但我认为它应该工作。 You might need to tinker with the dateadd stuff.. 你可能需要修补dateadd的东西..

Can you create a table variable with the dates that you need and then RIGHT JOIN onto it? 你能用你需要的日期创建一个表变量然后RIGHT JOIN它吗? For example, 例如,

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

The more ideal situation however, would be to have a table object with the dates in 然而,更理想的情况是拥有一个日期为的表对象

I would suggest the usage of a date table . 我建议使用日期表 With an existing date table in place, you can perform a RIGHT OUTER JOIN to the date table to bring in your missing days. 使用现有的日期表,您可以对日期表执行RIGHT OUTER JOIN以引入您的遗失日期。

Can you create the set of dates as part of your query? 您可以在查询中创建一组日期吗? Something along the lines of: 有点像:

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 ...

This is inspired by a sort of hybrid of Informix and DB2 notations and is pretty much guaranteed to be syntactically incorrect in both. 这是受到Informix和DB2符号的混合的启发,并且几乎可以保证在语法上都不正确。 Basically, is there a way in your DBMS of creating a literal table on the fly. 基本上,在DBMS中有一种方法可以动态创建文字表。 One possibility - ugly but barely doable - would be to do a 7-way UNION of date literals selected from 'dual' or some table expression that guarantees one row (in Informix terms, SELECT MDY(2,28,2009) FROM "informix".systables WHERE tabid = 1 UNION ... ). 一种可能性 - 丑陋但几乎不可行 - 将是从“双”或某些表表达式中选择的7路UNION日期文字,它保证一行(在Informix术语中, SELECT MDY(2,28,2009) FROM "informix".systables WHERE tabid = 1 UNION ... )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM