2017-05-17 63 views
2

我之间'01/05/2017' 年和'05/05/2017' 年,并返回行类似选取日期范围,加入

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 
选择查询

我试着加入日期范围,但无法得到我想要的结果。

 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 

我怎样才能得到这行?

+1

你在你的数据库中有一个'dates'表? –

+1

这些是你正在寻找的日期吗? [xkcd PSA ISO 8601](https://xkcd.com/1179/) – SqlZim

+1

加入日历表...有100个例子。 – scsimon

回答

2

您可以生成您的日期和cross join您的员工,然后left join到您的进入/退出时间表。

这将使用堆叠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 

更重要的是,你可以创建一个日期表。

对于内存只有152KB,可以有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]); 

号码和日历表参考:

+0

你的答案不完全是我想要的,但主要是它。你指导了我。谢谢。 – serdar

+0

@serdar乐于帮忙! – SqlZim