Sql server 2008 使用SQL将月末结账业务日期分组到bucket中
我目前正在使用这个逻辑来计算这些月末结账日期 (定义为当月最后一个营业日、下月第一个营业日和下月第二个营业日) 然后选择[MEC_IND]=1的日期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
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' */
)