【问题标题】:SQL server DATEADD specific week daysSQL 服务器 DATEADD 特定工作日
【发布时间】:2017-02-15 23:04:29
【问题描述】:

所以我需要给一个日期加上一些天,比如说30,但是30天不能是日历天,它们是依赖于一些逻辑的参数,所以,我需要找到一种方法来添加到星期一和星期三之间 30 天的日期,例如: 如果我在 2 月 15 日加上 30(周一到周三)天,我应该得到 4 月 26 日 如果我在 2 月 15 日加上 30(周日到周五)天,我应该得到 3 月 17 日

如果情况不够清楚,请告诉我蚂蚁,我会尽力给出更好的解释。

谢谢。

【问题讨论】:

  • 你是指工作日吗?
  • @McNets 好吧,有点,但不仅是工作日,它可能是从周日到周五,周一到周二......它变化很大,但如果有一种方法可以将所需的定义为工作日每个查询的天数,我都可以处理
  • 你有查找日历表吗?
  • 不,但我可以在程序结束时创建并销毁它
  • 你在用哪个 dbms?

标签: sql sql-server dateadd


【解决方案1】:

首先我在 StartDate 和 EndDate 之间生成了一系列日期,但它返回星期几:

SELECT  DATEPART(weekday, DATEADD(DAY, nbr - 1, @StartDate)) as dow
FROM    (SELECT    ROW_NUMBER() OVER ( ORDER BY c.object_id ) AS Nbr
         FROM      sys.columns c
         )nbrs
WHERE   nbr - 1 <= DATEDIFF(DAY, @StartDate, @EndDate)

然后您可以使用一个简单的 WHERE IN () 来选择您想要包含的星期几,并计算返回的天数。

DECLARE @StartDate DATE = '20170101'
        , @EndDate DATE = '20170131'

SELECT COUNT(*) AS DAYS
FROM (
        SELECT  DATEPART(weekday, DATEADD(DAY, nbr - 1, @StartDate)) as dow
        FROM    (SELECT    ROW_NUMBER() OVER ( ORDER BY c.object_id ) AS Nbr
                 FROM      sys.columns c
                )nbrs
        WHERE   nbr - 1 <= DATEDIFF(DAY, @StartDate, @EndDate)
    ) T1
WHERE DOW IN (3,4,5);

在您的 SQL Server 中处理一周中的第一天,您可以使用 SET DATEFIRST 更改它。

在这里查看:http://rextester.com/WCLIXM28868

【讨论】:

  • 看起来很棒!会试一试,让你知道!
  • 太棒了!这正是我一直在寻找的,快速且易于理解。谢谢!
  • 很高兴能提供帮助。
【解决方案2】:

我会用递归 CTE 来做,像这样:

-- set datefirst as Sunday. You may need to adjust it ot the correct Datefirst value for your locale
SET DATEFIRST 7

declare @d datetime
set @d = '2017-02-15'
SELECT @d

;with 
days as( 
-- this CTE where you define the active days. The days start 
select 1 as d, 0 as active -- sunday
union
select 2 as d, 1 as active -- monday
union 
select 3 as d, 1 as active
union 
select 4 as d, 1 as active
union 
select 5 as d, 0 as active
union 
select 6 as d, 0 as active 
union
select 7 as d, 0 as active -- saturday

),
n as (
select CASE WHEN DATEPART(dw, DATEADD(d, 1, @d)) IN (select d from days where active=1) THEN 1 ELSE 0 END as n, @d as dt
union all 
select CASE WHEN DATEPART(dw, DATEADD(d, 1, dt)) IN (select d from days where active=1) THEN n+1 else n end, DATEADD(d, 1, dt)
from n where n < 30)
--SELECT * from n order by n
SELECT top 1 @d = dt from n order by n desc

select @d

以上查询适用于周一至周三。使其在周日至周五修改 CTE 天的活动标志

【讨论】:

  • 这可能有效,因为我得到了天数(0=星期日,7=星期六),我可以在 CTE 使用 CASE WHEN...,我会尝试这种方法。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-10
  • 1970-01-01
相关资源
最近更新 更多