SQL adding missing dates to query

时间:2015-11-12 10:54:05

标签: sql sql-server datetime date-range

I'm trying to add missing dates to a SQL query but it does not work.

Please can you tell me what I'm doing wrong. I only have read only rights to database.

SQL query:

With cteDateGen AS
(
  SELECT 0 as Offset, CAST(DATEADD(dd, 0, '2015-11-01') AS DATE) AS WorkDate
  UNION ALL 
  SELECT Offset + 1, CAST(DATEADD(dd, Offset, '2015-11-05') AS DATE)
  FROM cteDateGen
  WHERE Offset < 100
), -- generate date from to --
cte AS (
    SELECT COUNT(*) OVER() AS 'total' ,ROW_NUMBER()OVER (ORDER BY c.dt DESC) as row
        , c.* 
    FROM clockL c
    RIGHT JOIN cteDateGen d ON CAST(c.dt AS DATE) = d.WorkDate
    WHERE 
        c.dt between '2015-11-01' AND '2015-11-05' and
        --d.WorkDate BETWEEN '2015-11-01' AND '2015-11-05' 
        and c.id =10
) -- select user log and add missing dates --  
SELECT * 
FROM cte 
--WHERE row BETWEEN 0 AND 15
--option (maxrecursion 0)

1 个答案:

答案 0 :(得分:0)

I think your problem is simply the dates in the CTE. You can also simplify it a bit:

With cteDateGen AS (
      SELECT 0 as Offset, CAST('2015-11-01' AS DATE) AS WorkDate
      UNION ALL 
      SELECT Offset + 1, DATEADD(day, 1, WorkDate) AS DATE)
      -----------------------------------^
      FROM cteDateGen
      WHERE Offset < 100
     ), -- generate date from to --
     cte AS
      (SELECT COUNT(*) OVER () AS total,
              ROW_NUMBER() OVER (ORDER BY c.dt DESC) as row,
              c.* 
       FROM cteDateGen d LEFT JOIN
            clockL c
            ON CAST(c.dt AS DATE) = d.WorkDate AND c.id = 10
-----------------------------------------------^
       WHERE d.WorkDate between '2015-11-01' AND '2015-11-05'
     ) -- select user log and add missing dates --  
SELECT * 
FROM cte 

Notes:

  • Your query used a constant for the second date in the CTE. The constant was different from the first constant. Hence, it was missing some days.
  • I think that LEFT JOIN is much easier to follow than RIGHT JOIN. LEFT JOIN is basically "keep all rows in the first table".
  • The WHERE clause was undoing the outer join in any case. The c.id logic needs to move to the ON clause.
  • The date arithmetic in the first CTE was unnecessarily complex.