2017-05-17 100 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