【问题标题】:How to assign a same number of business day as Monday to weekend days如何分配与星期一到周末相同的工作日数
【发布时间】:2015-06-24 01:26:35
【问题描述】:

我有一个日期维度表,我需要在其中添加 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

仅供参考 - 将周末记为工作日的目的是因为我们不想错过周末期间发生的任何活动(这是可能的),我们希望在下一个工作日计算这些活动。

【问题讨论】:

  • 如果您拥有最新版本的 SQL Server 之一,您可以使用 LEAD 函数
  • 周一非工作日你会做什么?
  • 当 DATENAME(dw,date) IN ('Saturday','SUNDAY') THEN NULL ELSE date END from table 时选择大小写
  • @Sachu 我已经发布了查询
  • @Dan Guzman 基本上是下一个工作日,在这种情况下是星期二。

标签: sql sql-server date business-intelligence


【解决方案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。我只将星期六标记为周末并填充表格

谢谢

【讨论】:

  • 非常感谢!!这很好用。我什至没有想到一个简单的逻辑——“更新表设置工作日 = 工作日 +1 哪里周末标志 =Y”。我只是要将假期更新为 0。再次感谢您!
  • 我在 CTE 中 order by 之前添加了 YearCode 和 MonthCode 的分区函数。这将给出每个月的工作日数,而不是全年。
【解决方案2】:

在 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。

【讨论】:

  • 这不起作用,我试图了解您的查询在做什么。我只在 2015 年这样做,它分配了以下数字:' Jan-1 = 0,Jan-2 = 0,Jan-3 = 1,Jan-4 = 2,Jan-5 = 2,Jan-6 = 2, Jan-7 = 2, Jan-8 = 2, Jan-9 = 2, Jan-10 = 3, Jan-11 = 4'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-19
  • 2020-08-12
  • 1970-01-01
  • 2012-11-27
  • 2017-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多