水平date间隔到垂直date(可能是一个SQL / VBA循环解决scheme?)

是否有更快的方法来转换我的数据从列a – d是人事信息,然后列e是离开开始日和列f是休假结束一天如下:

在每一行和列e上重复的a-d列是该范围内每个date/date的单独一行?

目前我正在手动准备大量休假。

我还应该补充说,每行都包含一个员工休假的时间间隔,同一个员工可能会在数据集中多次出现。

我正在阅读SQL脚本,虽然它似乎没有覆盖这种情况,为每个人创build了许多行和间隔。

如果你想在SQL中解决这个问题,那么你可以使用日历或date表来处理这种事情。

在内存中只有152kb,你可以在这个表中有30年的date:

/* 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]); 

没有采取创build表的实际步骤,您可以使用公共表expression式生成特别date表 :

 declare @fromdate date, @thrudate date; select @fromdate = min(fromdate), @thrudate = max(thrudate) from dbo.leave; ;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] ) 

像这样使用:

 /* `distinct` if there are overlaps or duplicates to remove */ select distinct l.personid , d.[Date] from dbo.leave l inner join dates d on d.date >= l.fromdate and d.date <= l.thrudate; 

rextester演示: http ://rextester.com/AVOIN59493

从这个testing数据:

 create table leave (personid int, fromdate date, thrudate date) insert into leave values (1,'20170101','20170107') ,(1,'20170104','20170106') -- overlapped ,(1,'20170420','20170422') ,(2,'20170207','20170207') -- single day ,(2,'20170330','20170405') 

收益:

 +----------+------------+ | personid | Date | +----------+------------+ | 1 | 2017-01-01 | | 1 | 2017-01-02 | | 1 | 2017-01-03 | | 1 | 2017-01-04 | | 1 | 2017-01-05 | | 1 | 2017-01-06 | | 1 | 2017-01-07 | | 1 | 2017-04-20 | | 1 | 2017-04-21 | | 1 | 2017-04-22 | | 2 | 2017-02-07 | | 2 | 2017-03-30 | | 2 | 2017-03-31 | | 2 | 2017-04-01 | | 2 | 2017-04-02 | | 2 | 2017-04-03 | | 2 | 2017-04-04 | | 2 | 2017-04-05 | +----------+------------+ 

数字和日历表格参考:

  • 生成一个没有循环的集合或序列 – 2 – Aaron Bertrand
  • “数字”或“理货”表:它是什么以及它如何取代一个循环 – 杰夫·莫德恩
  • 在SQL Server 2008中创builddate表/维度 – David Stein
  • 日历表 – 为什么你需要一个 – 大卫斯坦
  • 在SQL Server中创builddate维度或日历表 – Aaron Bertrand

伙计们,我怎么解决这个实际上只是使用另一个公式在这个论坛涉及join和date间隔。

工作很好!

Ps将日历用于考虑周末和公众假期的实际工作日的另一场景….

谢谢