如何为周一到周末分配相同数量的工作日

时间:2015-06-24 01:26:36

标签: sql sql-server date business-intelligence

我有一个日期维度表,我需要添加NumberofBusinessDay列,它会告诉我它的营业日数。例如:

Date        WeekendFlag  BusinessDayFlag  **NumberofBusinessDay** 
01/01/2015  N            N                0
01/02/2015  N            Y                1
01/03/2015  Y            N                2
01/04/2015  Y            N                2
01/05/2015  N            Y                2

我已经将工作日的数量分配到工作日但我正在努力为周末日分配一个数字,这与下一个工作日相同 - 周一(如果周一是假日,则是周二) ,如上表所示。这就是我到目前为止所做的:

Date        WeekendFlag  BusinessDayFlag  **NumberofBusinessDay** 
01/01/2015  N            N                0
01/02/2015  N            Y                1
01/03/2015  Y            N                NULL
01/04/2015  Y            N                NULL
01/05/2015  N            Y                2 

任何形式的帮助将不胜感激

我在工作日分配BusinessDays的查询(仅限2015年数据):

SELECT Date, WeekendFlag, BusinessDayFlag
       ,NumberofBusinessDay = CASE WHEN WeekendFlag = 'N' THEN 
       ROW_NUMBER() OVER (Partition BY YearCode, MonthCode ORDER BY WeekendFlag, Date ASC) 
       END
INTO #test
FROM DimDate
WHERE Date between '01/01/2015' AND '12/31/2015' --for testing purposes only
ORDER BY Date ASC

仅仅是一个FYI - 会计周末作为工作日的目的是因为我们不想错过周末期间发生的任何活动(可能性),我们希望在下一个工作日计算这些活动。 / p>

2 个答案:

答案 0 :(得分:1)

在SQL Server 2012+中,您可以使用累积总和来执行此操作:

select dd.*,
       sum(case when BusinessDayFlag = 'Y' then 1 else 0 end) over (order by date) as NumberOfBusinessDay
from DateDimension;

您可以将其更新为:

with toupdate as (
      select dd.*,
             sum(case when BusinessDayFlag = 'Y' then 1 else 0 end) over (order by date) as newNumberOfBusinessDay
      from DateDimension
     )
update toupdate
    set NumberOfBusinessDay = newNumberOfBusinessDay;

在早期版本的SQL Server中,您可以使用cross apply执行类似操作。

编辑:

根据您的示例数据,您似乎计算工作日的数量,而不是工作日。如果是这样,上面只是使用了错误的变量:

with toupdate as (
      select dd.*,
             sum(case when WeekEndFlag = 'N' then 1 else 0 end) over (order by date) as newNumberOfBusinessDay
      from DateDimension
     )
update toupdate
    set NumberOfBusinessDay = newNumberOfBusinessDay;

这取决于您的示例结果。请注意,这可能是1分之一,因此您应该减去1.但是,从描述来看,我不会这样做。理解为什么第一行的值为0而不是1。

答案 1 :(得分:1)

用下面的sql检查

---- below code will crete table for businessday calculation
create table dimension  (calenderdate date,WeekendFlag  char(1) ,BusinessDayFlag   char(1),NumberofBusinessDay int)

declare  @yearstartdate date
declare  @yearenddate date

SELECT   @yearstartdate = DATEADD(yy, DATEDIFF(yy,0,getdate()), 0) 
SELECT   @yearenddate =DATEADD(yy, DATEDIFF(yy,0,getdate()) + 1, -1)

while datediff (dd,@yearstartdate,DATEADD(DD,1,@yearenddate)) <>0
begin
	insert into dimension 
	select @yearstartdate ,
	case when datename(DW,@yearstartdate) = 'SUNDAY' or datename(DW,@yearstartdate) = 'SATURDAY'
	then 'Y' else 'N' end,
	case when datename(DW,@yearstartdate) = 'SUNDAY' or datename(DW,@yearstartdate) = 'SATURDAY'
	then 'N' else 'Y' end,
	null

	set @yearstartdate = dateadd(dd,1,@yearstartdate)
end
-----verify table
SELECT * FROM dimension 

-----calculate NumberofBusinessDay number  from below code

;with ctebusinessday
as
(
 select calenderdate,
sum(
case when BusinessDayFlag = 'Y' then 1 else 0 end
   ) over (order by calenderdate) as NOfBusinessDay
   from dimension 
)
update b
set b.NumberofBusinessDay =c.NOfBusinessDay
from dimension  b join ctebusinessday c
on b.calenderdate = c.calenderdate
	 
	 
update dimension 
set NumberofBusinessDay = NumberofBusinessDay + 1
where weekendflag = 'Y'
--verify table
select * from dimension

您可以将任何日期更新为营业日或周末日,并从NumberofBusinessDay计算代码部分计算NumberofBusinessDay。我只将saturaday标记为周末和填充表

谢谢