SQL日期范围截至上个月和上一年的年初至今

时间:2017-01-16 18:52:00

标签: sql-server date

查询日期范围需要在上个月的结束日期和上一年的相应日期范围之间。我有一个'公式'它通过月份和年份的数值定义日期范围。例如上个月的结束是当月减1。这个工作很有效,直到我一月份成为今年的第一年,我无法使用当年。

我不是一个经验丰富的SQL用户,并且已经使用谷歌来学习我所知道的大部分内容,但是没有成功找到这个问题的答案 - 找出上个月结束的公式,但不是剩下的以下三个日期。

DECLARE @PYStart datetime = '1/1/2015'
DECLARE @PYEnd datetime = '12/31/2015' 
DECLARE @CYStart datetime = '1/1/2016' -- first day of previous month's year
DECLARE @CYEnd datetime = CONVERT(varchar, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0)),101) -- last day of past month

SELECT YEAR(transaction_date) as 'Year', MONTH(transaction_date) as 'Month'

FROM TABLE_Q1

WHERE((transaction_date BETWEEN @pystart and @pyend) OR (transaction_date BETWEEN @cystart AND @cyend))

group by year(transaction_date), month(transaction_date)

- 输出如下; Example output if you were to run today

1 个答案:

答案 0 :(得分:0)

这实际上是相当直接的,尽管最好的方法取决于您将从范围中选择日期的字段是否包含时间。这个答案处理两种情况。

DECLARE @CYEnd datetime = CONVERT(varchar, DATEADD(day, -(DATEPART(day, GETDATE()) - 1), 101) -- First day of Current month
DECLARE @CYStart datetime = Cast(Cast(DATEPART(year, DATEADD(day, -1, @CYEnd)) as varchar(4)) + '0101' AS date)
DECLARE @PYEnd datetime = DATEADD(year, -1, @CYEnd)
DECLARE @PYStart datetime = dateadd(year, -1, @CYStart)

SELECT YEAR(transaction_date) as 'Year', 
    MONTH(transaction_date) as 'Month'
FROM TABLE_Q1

WHERE 
    (transaction_date >= @pystart and transaction_date < @pyend) 
    OR 
    (transaction_date >= @cystart AND transaction_date < @cyend)
group by 
    year(transaction_date), 
    month(transaction_date)

工作原理 让我们假设当前日期是2016年3月10日。在这种情况下,@ CYEnd中的值将是2016-03-01,而@PYEnd将是2015-03-01。无论是否附加时间,检查(transaction_date >= @pystart and transaction_date < @pyend)(transaction_date >= @cystart AND transaction_date < @cyend)都将正确返回所需的记录。使用2016-02-29作为@CYEnd的BETWEEN测试将错过包含时间的所有日期,但如果没有时间被记录为被过滤字段的一部分,它将返回正确的答案。

这也优雅地处理闰年,因为02/29或02/28都是&lt; 03/01