添加缺少日期以进行查询

时间:2017-05-24 07:41:36

标签: sql sql-server

我一直致力于查询,该查询根据员工的工作小时数返回日期。如果某个日期没有工作时间,则也不会为员工创建日期。例如:

SELECT TOP 1000 SUM(AantalUur) as Uren, GewerktopDatum as Datum
  FROM db gu
 JOIN Medewerkers m on m.medewerker_pk = gu.medewerker_fk
  Where m.Voornaam = 'name' 
  and COALESCE(m.Tussenvoegsel,'') LIKE 'name' 
  and m.Achternaam = 'name' 
  and GewerktOpDatum between '2017-05-16 00:00:00.0' and  '2017-05-23 00:00:00.0'
  and UrenPerWeek > 0
        GROUP BY GewerktOpDatum

返回的值为:

8       2017-05-16 00:00:00.000
8       2017-05-17 00:00:00.000
8       2017-05-18 00:00:00.000
6       2017-05-19 00:00:00.000
8       2017-05-22 00:00:00.000
6,5     2017-05-23 00:00:00.000

基本上, 我还想要退回2017-05-20和2017-05-21,即使这些不在数据库中。

我将如何做到这一点?

2 个答案:

答案 0 :(得分:1)

根据@ TimBiegeleisen的建议,您可以使用Recursive CTE之前的日历表。

DECLARE @StartDate date  = dateadd(month, -3, getdate()) -- or other day that you want....
DECLARE @EndDate date = getdate()

;WITH temp AS
(
    SELECT @StartDate AS DateValue
    UNION ALL
    SELECT dateadd(day,1,t.DateValue)
    FROM temp t
    WHERE t.DateValue <= @EndDate
)
SELECT t.DateValue, ISNULL(d.Uren ,0) AS Uren
FROM temp t
LEFT JOIN
(
  SELECT TOP 1000 SUM(AantalUur) as Uren, GewerktopDatum as Datum
  FROM db gu
    JOIN Medewerkers m on m.medewerker_pk = gu.medewerker_fk
  Where m.Voornaam = 'name' 
     and COALESCE(m.Tussenvoegsel,'') LIKE 'name' 
     and m.Achternaam = 'name' 
     and GewerktOpDatum between '2017-05-16 00:00:00.0' and  '2017-05-23 00:00:00.0'
     and UrenPerWeek > 0
  GROUP BY GewerktOpDatum

) d ON t.DateValue = d.Datum

答案 1 :(得分:0)

你必须加入一个压缩表。例如:

-- This will create a date range from 01-01-1900 to 01-01-2050
SELECT      DATEADD(DAY, X.RN - 1, '19000102') Dates
INTO        dbo.Calander
FROM        (
                SELECT      TOP (DATEDIFF(DAY, '19000102', '20500101')) ROW_NUMBER() OVER(ORDER BY S1.object_id) RN
                FROM        sys.all_objects S1
                CROSS JOIN  sys.all_objects S2
            ) X

SELECT      TOP 1000 SUM(AantalUur) as Uren
,           C.Dates as Datum
FROM        db gu
JOIN        Medewerkers m 
    ON      m.medewerker_pk = gu.medewerker_fk
RIGHT JOIN  dbo.Calander C
        ON  C.Dates = m.GewerktOpDatum -- I assumed this is where GewerktOpDatum is. You should use aliases to make clear where attributes are coming from.
Where       m.Voornaam = 'name' 
        and COALESCE(m.Tussenvoegsel,'') LIKE 'name' 
        and m.Achternaam = 'name' 
        and C.Dates between '2017-05-16 00:00:00.0' and  '2017-05-23 00:00:00.0'
        and UrenPerWeek > 0
GROUP BY    C.Dates