SQL 日期逻辑 - 查找之前的*非标准*季度
SQL date logic - finding prior *non-standard* quarter
SQL 服务器 2012。
我们有一个使用非标准季度报告的业务部门。季度从 11 月开始,到 10 月结束。为了强调这一点,Q1:11 月到 1 月; Q2:二月到四月; Q3:5-7月; Q4:8月至10月
我正在尝试创建一个“简单而高效”的查询,它可以根据这个非标准方案获取给定日期和 return 上一个“季度”的第一个和最后一个日期。
一位前同事使用非常笨拙的复杂 case 表达式处理了这个问题,我想找到更好的方法。
我知道 SQL 服务器有一些处理季度的内置日期逻辑,但仅限于标准日历季度。因此,以下将可靠地 return 上一季度的第一天,但只是从 1 月开始到 12 月结束的季度标准方案...
SELECT DATEADD(quarter, DATEDIFF(quarter, 0, GETDATE()) - 1, 0)
--Shows first day of prior quarter, but only for 'standard' quarters
然后我天真地以为只要减去两个月就可以了,但是有 2/3 的时候这是错误的
SELECT DATEADD(month, -2, DATEADD(quarter, DATEDIFF(quarter, 0, GETDATE()) - 1, 0))
--Works for 1/3 dates
从那时起,我尝试了各种嵌套计算方案,但没有任何效果。
任何人都可以帮助我进行此计算 - 或者您会建议我只创建一个日期 table 让我查找非标准季度吗?谢谢
您可以使用以下查询:-
DECLARE @mydate DATETIME ='2020-04-04'
SELECT
CASE
WHEN MONTH(@mydate) BETWEEN 2 AND 4 THEN CAST(YEAR(@mydate) - 1 as varchar)+'-11-01'
WHEN MONTH(@mydate) BETWEEN 5 AND 7 THEN CAST(YEAR(@mydate) as varchar)+'-02-01'
WHEN MONTH(@mydate) BETWEEN 8 AND 10 THEN CAST(YEAR(@mydate) as varchar)+'-05-01'
WHEN MONTH(@mydate) in(11,12) THEN CAST(YEAR(@mydate) as varchar)+'-08-01'
WHEN MONTH(@mydate)=1 THEN CAST(YEAR(@mydate) -1 as varchar)+'-08-01'
END AS Start_date,
CASE
WHEN MONTH(@mydate) BETWEEN 2 AND 4 THEN CAST(YEAR(@mydate) as varchar)+'-01-31'
WHEN MONTH(@mydate) BETWEEN 5 AND 7 THEN CAST(YEAR(@mydate) as varchar)+'-04-30'
WHEN MONTH(@mydate) BETWEEN 8 AND 10 THEN CAST(YEAR(@mydate) as varchar)+'-07-31'
WHEN MONTH(@mydate) in(11,12) THEN CAST(YEAR(@mydate) as varchar)+'-10-31'
WHEN MONTH(@mydate)=1 THEN CAST(YEAR(@mydate) -1 as varchar)+'-10-31'
END AS End_date
您可以根据需要使用以下查询来确定上一季度的第一个和最后一个日期:
declare @date date = getdate()
select case
when MONTH(@date) in (11,12,1) then datefromparts(year(@date),8,1)
when MONTH(@date) in (8,9,10) then datefromparts(year(@date),5,1)
when MONTH(@date) in (5,6,7) then datefromparts(year(@date),2,1)
when MONTH(@date) in (2,3,4) then datefromparts(year(@date),11,1)
end StartOfPreviousQuarter,
case
when MONTH(@date) in (11,12,1) then datefromparts(year(@date),8,30)
when MONTH(@date) in (8,9,10) then datefromparts(year(@date),5,31)
when MONTH(@date) in (5,6,7) then
CASE WHEN ISDATE(CAST(year(@date) AS char(4)) + '0229') = 1 THEN datefromparts(year(@date),2,29) ELSE datefromparts(year(@date),2,28) END
when MONTH(@date) in (2,3,4) then datefromparts(year(@date),11,30)
end EndOfPreviousQuarter
我会加上两个月,取季度的第一天,然后减去两个月:
SELECT DATEADD(month, -2,
DATEADD(quarter,
DATEDIFF(quarter, 0, DATEADD(month, 2, GETDATE())
) - 1, 0
)
) as Special_Quarter_Date
我更倾向于使用 DATEFROMPARTS()
:
来写
select dateadd(month, -2,
datefromparts( year(dateadd(month, 2, getdate()),
datepart(quarter, dateadd(month, 2, getdate()) * 3 - 2
1
)
)
但逻辑完全一样:加两个月,计算季度,减去两个月。
SQL 服务器 2012。
我们有一个使用非标准季度报告的业务部门。季度从 11 月开始,到 10 月结束。为了强调这一点,Q1:11 月到 1 月; Q2:二月到四月; Q3:5-7月; Q4:8月至10月
我正在尝试创建一个“简单而高效”的查询,它可以根据这个非标准方案获取给定日期和 return 上一个“季度”的第一个和最后一个日期。
一位前同事使用非常笨拙的复杂 case 表达式处理了这个问题,我想找到更好的方法。
我知道 SQL 服务器有一些处理季度的内置日期逻辑,但仅限于标准日历季度。因此,以下将可靠地 return 上一季度的第一天,但只是从 1 月开始到 12 月结束的季度标准方案...
SELECT DATEADD(quarter, DATEDIFF(quarter, 0, GETDATE()) - 1, 0)
--Shows first day of prior quarter, but only for 'standard' quarters
然后我天真地以为只要减去两个月就可以了,但是有 2/3 的时候这是错误的
SELECT DATEADD(month, -2, DATEADD(quarter, DATEDIFF(quarter, 0, GETDATE()) - 1, 0))
--Works for 1/3 dates
从那时起,我尝试了各种嵌套计算方案,但没有任何效果。
任何人都可以帮助我进行此计算 - 或者您会建议我只创建一个日期 table 让我查找非标准季度吗?谢谢
您可以使用以下查询:-
DECLARE @mydate DATETIME ='2020-04-04'
SELECT
CASE
WHEN MONTH(@mydate) BETWEEN 2 AND 4 THEN CAST(YEAR(@mydate) - 1 as varchar)+'-11-01'
WHEN MONTH(@mydate) BETWEEN 5 AND 7 THEN CAST(YEAR(@mydate) as varchar)+'-02-01'
WHEN MONTH(@mydate) BETWEEN 8 AND 10 THEN CAST(YEAR(@mydate) as varchar)+'-05-01'
WHEN MONTH(@mydate) in(11,12) THEN CAST(YEAR(@mydate) as varchar)+'-08-01'
WHEN MONTH(@mydate)=1 THEN CAST(YEAR(@mydate) -1 as varchar)+'-08-01'
END AS Start_date,
CASE
WHEN MONTH(@mydate) BETWEEN 2 AND 4 THEN CAST(YEAR(@mydate) as varchar)+'-01-31'
WHEN MONTH(@mydate) BETWEEN 5 AND 7 THEN CAST(YEAR(@mydate) as varchar)+'-04-30'
WHEN MONTH(@mydate) BETWEEN 8 AND 10 THEN CAST(YEAR(@mydate) as varchar)+'-07-31'
WHEN MONTH(@mydate) in(11,12) THEN CAST(YEAR(@mydate) as varchar)+'-10-31'
WHEN MONTH(@mydate)=1 THEN CAST(YEAR(@mydate) -1 as varchar)+'-10-31'
END AS End_date
您可以根据需要使用以下查询来确定上一季度的第一个和最后一个日期:
declare @date date = getdate()
select case
when MONTH(@date) in (11,12,1) then datefromparts(year(@date),8,1)
when MONTH(@date) in (8,9,10) then datefromparts(year(@date),5,1)
when MONTH(@date) in (5,6,7) then datefromparts(year(@date),2,1)
when MONTH(@date) in (2,3,4) then datefromparts(year(@date),11,1)
end StartOfPreviousQuarter,
case
when MONTH(@date) in (11,12,1) then datefromparts(year(@date),8,30)
when MONTH(@date) in (8,9,10) then datefromparts(year(@date),5,31)
when MONTH(@date) in (5,6,7) then
CASE WHEN ISDATE(CAST(year(@date) AS char(4)) + '0229') = 1 THEN datefromparts(year(@date),2,29) ELSE datefromparts(year(@date),2,28) END
when MONTH(@date) in (2,3,4) then datefromparts(year(@date),11,30)
end EndOfPreviousQuarter
我会加上两个月,取季度的第一天,然后减去两个月:
SELECT DATEADD(month, -2,
DATEADD(quarter,
DATEDIFF(quarter, 0, DATEADD(month, 2, GETDATE())
) - 1, 0
)
) as Special_Quarter_Date
我更倾向于使用 DATEFROMPARTS()
:
select dateadd(month, -2,
datefromparts( year(dateadd(month, 2, getdate()),
datepart(quarter, dateadd(month, 2, getdate()) * 3 - 2
1
)
)
但逻辑完全一样:加两个月,计算季度,减去两个月。