我道歉,我不确定如何说出这个问题的标题。如果有人可以为我改革,以便更好地适应我的要求,我将不胜感激。
我有一个很长的问题,我被困在了最长的时间。我将Tableau与SQLServer 2014结合使用。
我有一张表,基本上显示了我们公司内的所有员工。他们的雇用日期和终止日期(如果仍然使用,则为NULL)。我希望能够产生过去的人数。以下是此表的示例:
employeeID HireDate TermDate FavouriteFish FavouriteColor
1 1/1/15 1/1/18 Cod Blue
2 4/12/16 NULL Bass Red
.
.
.
n
正如你所看到的,这个列表可以继续下去。实际上,我所讨论的表格目前有超过10000行供所有过去和现在的员工使用。
我的目标是构建一个视图,以查看过去5年中每年的每一天我们雇用的员工总人数。以下是踢球者......我需要保留其余的信息,例如:
FavouriteFish FavouriteColor... and so on
我能想到这样做的唯一方法是,它工作得非常好,因为它非常慢,是为过去5年的每一天创建一个单独的日历表;像这样:
Date CrossJoinKey
1/1/2013 1
1/2/2013 1
1/3/2013 1
.
.
.
4/4/2018 1
从这里开始,我在原来的Employee Table中添加了一个列:CrossJoinKey;像这样......
employeeID HireDate TermDate FavouriteFish FavouriteColor CrossJoinKey
1 1/1/15 1/1/18 Cod Blue 1
2 4/12/16 NULL Bass Red 1
.
.
.
n
从这里我创建一个LEFT JOIN Calendar ON Employee.CrossKeyJoin=Calendar.CrossKeyJoin
希望在这里你可以立即看到问题..它与很多行创造了一种关系!事实上它给了我大约1800万行。它为我提供了我所追求的信息,但是查询需要很长时间,当我将其导入Tableau以创建提取时,它也需要很长时间才能完成。但是,一旦Tableau最终创建了提取它比较快我可以使用内部胆量来隔离并在过去5年内创建一个人数...通过查看date
字段是否在termDate
和HireDate
之间。但是整个过程需要经常进行,我觉得当前的方法不实用。
我觉得这是一种天真的方式来完成我所追求的目标,我觉得这个问题必须在过去之前得到解决。这里有没有人能够对如何优化这一点有所了解?
值得注意的是......我已经考虑过本质上创建一个查询,通过查看员工表并“计算”仍然使用的每个员工来填充日历表,但这种方法失去了解决方案,我无法保留员工的任何其他数据。
这样的东西,如下所示,效果更好,但不是我想要的东西:
Date HeadCount
1/1/2013 1200
1/2/2013 1201
1/3/2013 1200
.
.
.
4/4/2018 5000
非常感谢你花了一些时间。
更新: 这是指向google sheets data sample
的链接答案 0 :(得分:0)
我已经编辑了一些数据,您可以在@example表中看到。
我想注意:你要么拼写= D喜欢或颜色不正确,请更正它,要么是FavoriteColor,要么是FavouriteColour。
declare @example as table (
exampleid int identity(1,1) not null primary key clustered
, StartDate date not null
, TermDate date null
);
insert into @example (StartDate, TermDate)
select '1/1/2016', '1/1/2018' union all
select '4/3/2017', '1/10/2018' union all
select '9/3/2016', '2/4/2018' union all
select '5/9/2017', '11/21/2017' union all
select '9/18/2016', '11/15/2017' union all
select '12/12/2015', '2/8/2018' union all
select '6/18/2016', '12/20/2017' union all
select '7/26/2015', '11/4/2017' union all
select '1/7/2015', NULL union all
select '10/2/2013', '10/21/2013' union all
select '10/14/2013', '12/12/2017' union all
select '10/11/2013', '11/3/2017' union all
select '6/30/2015', '1/12/2018' union all
select '2/17/2016', NULL union all
select '8/12/2015', '11/26/2017' union all
select '12/2/2015', '11/15/2017' union all
select '3/30/2016', '11/30/2017' union all
select '6/18/2016', '11/9/2017' union all
select '4/3/2017', '2/12/2018' union all
select '3/26/2017', '1/15/2018' union all
select '1/27/2017', NULL union all
select '7/29/2016', '1/10/2018';
--| This is an adaption of Aaron Bertrand's work (time dim table)
--| this will control the start date
declare @date datetime = '2013-10-01';
;with cte as (
select 1 ID
, @date date_
union all
select ID + 1
, dateadd(day, 1, date_)
from cte
)
, cte2 as (
select top 1000 ID
, cast(date_ as date) date_
, 0 Running
, iif(datepart(weekday, date_) in(1,7), 0,1) isWeekday
, datepart(weekday, date_) DayOfWeek
, datename(weekday, date_) DayOfWeekName
, month(date_) Month
, datename(month, date_) MonthName
, datepart(quarter, date_) Quarter
from cte
--option (maxrecursion 1000)
)
, cte3 as (
select a.id
, Date_
, b.StartDate
, iif(b.StartDate is not null, 1, 0) Add_
, iif(c.TermDate is not null, -1, 0) Remove_
from cte2 a
left join @example b
on a.date_ = b.StartDate
left join @example c
on a.date_ = c.TermDate
-- option (maxrecursion 1000)
)
select date_
--, Add_
--, Remove_
, sum((add_ + remove_)) over (order by date_ rows unbounded preceding) CurrentCount
from cte3
option (maxrecursion 1000)
结果集:
date_ CurrentCount
2013-10-01 0
2013-10-02 1
2013-10-03 1
2013-10-04 1
2013-10-05 1