Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2008 使用SQL将月末结账业务日期分组到bucket中_Sql Server 2008_Date_Grouping_Dimensions - Fatal编程技术网

Sql server 2008 使用SQL将月末结账业务日期分组到bucket中

Sql server 2008 使用SQL将月末结账业务日期分组到bucket中,sql-server-2008,date,grouping,dimensions,Sql Server 2008,Date,Grouping,Dimensions,我目前正在使用这个逻辑来计算这些月末结账日期 (定义为当月最后一个营业日、下月第一个营业日和下月第二个营业日) 然后选择[MEC_IND]=1的日期 SELECT Date_Value, FIRST_DAY_OF_CALENDAR_MONTH_DATE FROM ... WHERE C.MEC_IND = 1 利用这种逻辑,我成功地以这种方式获得了日期 我如何修改逻辑,将这些月底结束业务日期分组到这样的桶中 请记住,我使用的是SQL Serv

我目前正在使用这个逻辑来计算这些月末结账日期

(定义为当月最后一个营业日、下月第一个营业日和下月第二个营业日)

然后选择[MEC_IND]=1的日期

 SELECT 
       Date_Value,
       FIRST_DAY_OF_CALENDAR_MONTH_DATE
FROM ...       
WHERE  C.MEC_IND = 1
利用这种逻辑,我成功地以这种方式获得了日期

我如何修改逻辑,将这些月底结束业务日期分组到这样的桶中

请记住,我使用的是SQL Server 2008,不能使用超前和滞后函数


有人能指引我吗?任何帮助都将不胜感激。提前感谢。

我能想到的最直接的方法是使用
dateadd()
case
表达式根据
day()
添加一个月或零个月,并将结果截断到月初

在此示例中使用特殊日期表:

declare @fromdate date = '20170428'
declare @thrudate date = '20170704'
;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]
)
select 
    date = [Date]
  , EffectiveMonth = dateadd(month
        , datediff(month, 0
          , dateadd(month,case when day(date) > 27 then 1 else 0 end, [Date])
        )
      , 0)
from dates
where day(date) <4 or day(date) > 27; -- for brevity in results

要分解表达式,组合的两个主要部分是
dateadd()
,它使用
case
表达式来确定是否应添加月份(该月的最后一个营业日)和日期截断

带有
大小写的
dateadd()
表达式是:

dateadd(month
  , case when day(date) > 27 then 1 else 0 end
  , [Date])

将日期截断为每月的第一天很简单,尽管语法可能不直观。将自
1900-01-01
以来的月数添加到日期
1900-01-01
可以将日期截断为月初

例如,对于当前日期:

select dateadd(month, datediff(month, 0, getdate() ), 0)
同一表达式的注释版本:

select dateadd(month 
      , datediff(month
        , 0 /* '19000101' */
        , getdate() /* date */
        ) /* end of datediff, returns integer number of months */ 
      , 0 /* '19000101' */
      )

将日期trunction与我们用case表达式导出的日期结合起来,结果如下:

select dateadd(month 
      , datediff(month
        , 0 /* '19000101' */
        , dateadd(month
          , case when day([Date]) > 27 then 1 else 0 end
          , [Date]) /* date */
      ) /* end of datediff, returns integer number of months */ 
  , 0 /* '19000101' */
  )

谢谢你的回答,我会测试一下tonight@kage77很乐意帮忙!我唯一的补充问题是,你是否可以在逻辑上添加一些评论,我不确定我是否完全理解这里发生的事情。那真的很有帮助。:)@kage77我为这个表达添加了一个解释,如果你有任何问题,请告诉我。
select dateadd(month 
      , datediff(month
        , 0 /* '19000101' */
        , getdate() /* date */
        ) /* end of datediff, returns integer number of months */ 
      , 0 /* '19000101' */
      )
select dateadd(month 
      , datediff(month
        , 0 /* '19000101' */
        , dateadd(month
          , case when day([Date]) > 27 then 1 else 0 end
          , [Date]) /* date */
      ) /* end of datediff, returns integer number of months */ 
  , 0 /* '19000101' */
  )