水平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将日历用于考虑周末和公众假期的实际工作日的另一场景….
谢谢