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

后端 未结 4 1221
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-18 12:06

I\'m using MS SQL Server but welcome comparitive solutions from other databases.

This is the basic form of my query. It returns the number of calls per day from the

相关标签:
4条回答
  • 2021-01-18 12:42

    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. Basically, is there a way in your DBMS of creating a literal table on the fly. 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 ...).

    0 讨论(0)
  • 2021-01-18 12:44

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

    0 讨论(0)
  • 2021-01-18 12:52

    Can you create a table variable with the dates that you need and then RIGHT JOIN onto it? 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

    0 讨论(0)
  • 2021-01-18 13:00

    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.

    0 讨论(0)
提交回复
热议问题