2017-01-16 204 views
-1

查询日期范围需要年份至上个月末的日期和上一年的相应日期范围。我有一个'公式',通过月份和年份的数值来定义日期范围。例如上个月的结束是本月减去一个月。这工作很好,直到我打1月份,是今年的第一个,我不能使用当年。SQL日期范围年初至上一个月的上一年和上一年

我不是一个有经验的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

+0

年初至今的原因是什么? –

+0

向我们展示示例数据和预期输出。 \t请阅读[**如何提问**](http://stackoverflow.com/help/how-to-ask) \t \t这里是一个伟大的地方[** START **] (http://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/)来了解如何提高您的问题质量并获得更好的答案。 –

+0

年初至今。对于这个例子来说,截至上个月的结束将是年初至今。例如。截至今天,它将是2016年1月1日至2016年12月31日,但说今年3月将是2017年1月1日 - 2017年2月28日 –

回答

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) 

它是如何工作 让我们假设当前的日期是3月10日,2016年在此情况下,在@CYEnd的价值将是2016年3月1日,和@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都是< 03/01。

+0

非常感谢您花时间帮助我!它的工作原理也非常有用,逻辑清晰,并且有很大的意义。肯定会在其他日期范围内使用。当我运行查询时,它导致了一个错误,我追溯到当前年底(@CYEnd)。我用CONVERT(varchar,DATEADD(s,-1,DATEADD(mm,DATEDIFF(m,0,GETDATE()),0)),101代替了@CYEnd的公式,它的工作非常好。我不完全确定它为什么不起作用(可能是我的目标),但它现在运行平稳,并感谢您的帮助!这是一个很棒的学习体验! –

相关问题