Select 加入日期范围

Select Date Range Join

我有一个查询,它在“01/05/2017”和“05/05/2017”和 returns 行之间选择

Date       EmployeeCode  EmployeeName  EntryTime   ExitTime
01/05/2017     10             a           08:00       18:00
02/05/2017     10             a           08:30       17:30
03/05/2017     10             a           08:30       17:30
03/05/2017     10             c           07:30       19:30
04/05/2017     10             c           09:30       18:30
05/05/2017     10             c           08:30       15:30

但我想看

Date       EmployeeCode  EmployeeName  EntryTime   ExitTime
01/05/2017     10             a           08:00       18:00
02/05/2017     10             a           08:30       17:30
03/05/2017     10             a           08:30       17:30
04/05/2017     10             a             -          -
05/05/2017     10             a           08:30       17:30
01/05/2017     10             c             -          -
02/05/2017     10             c             -          -
03/05/2017     10             c           07:30       19:30
04/05/2017     10             c           09:30       18:30
05/05/2017     10             c           08:30       15:30

I tried join with date range but could not get result as I want.

     WITH mycte AS
 (
  SELECT CAST('2017-05-01' AS DATETIME) DateValue
  UNION ALL
  SELECT  DateValue + 1
  FROM    mycte   
  WHERE   DateValue + 1 <= CAST('2017-05-05' AS DATETIME)
 )

 SELECT  
 DateValue
 FROM mycte 

How can I get this rows ?

您可以生成您的日期和 cross join 您的员工,然后 left join 到您的 entry/exit 次 table。

这使用堆叠式 cte 生成日期:

declare @fromdate date = '20170401'
declare @thrudate date = '20170505'
;with n as (select n from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(n))
, dates as (
  select top (datediff(day, @fromdate, @thrudate)+1) 
      [Date]=convert(date,dateadd(day,row_number() over(order by (select 1))-1,@fromdate))
  from n as deka cross join n as hecto cross join n as kilo
                cross join n as tenK cross join n as hundredK
   order by [Date]
)
select d.[Date], e.EmployeeCode, e.EmployeeName, t.EntryTime, t.ExitTime
from dates d
  cross join (
    select EmployeeCode, EmployeeName
    from Employees
    ) e
  left join TimeCard t
    on t.Date = d.Date
   and t.EmployeeCode = e.EmployeeCode

更好的是,您可以创建日期 table。

对于只有 152kb 的内存,你可以在一个 table 中有 30 年的日期:

/* dates table */
declare @fromdate date = '20000101';
declare @years    int  = 30;
/* 30 years, 19 used data pages ~152kb in memory, ~264kb on disk */
;with n as (select n from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(n))
select top (datediff(day, @fromdate,dateadd(year,@years,@fromdate)))
    [Date]=convert(date,dateadd(day,row_number() over(order by (select 1))-1,@fromdate))
into dbo.Dates
from n as deka cross join n as hecto cross join n as kilo
               cross join n as tenK  cross join n as hundredK
order by [Date];
create unique clustered index ix_dbo_Dates_date on dbo.Dates([Date]);

数字和日历table参考: