我有一个查询在'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
如何获取此行?
答案 0 :(得分: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]);
数字和日历表参考: