【问题标题】:Obtain date for prior month and prior year issue?获取上个月和上年问题的日期?
【发布时间】:2018-01-05 01:42:00
【问题描述】:

我有以下 SQL 语句,大部分情况下它对我有用,至少我是这么认为的。我需要以 MM/DD/YYYY 格式返回上个月的第一天。现在我们进入了新的一年(特别是一月),这是不正确的。

SELECT convert(char(10),DATEADD(year,-1,DATEADD(month, DATEDIFF(MONTH, 0, getdate())-1, 0)),120) AS LastYearFirstOfPreviousMonth

如果我在 2 月 1 日使用它,以后效果会很好!

SELECT convert(char(10),DATEADD(year,-1,DATEADD(month, DATEDIFF(month, 0, '2018-02-01')-1, 0)),120) AS LastYearFirstOfPreviousMonth

如果是“2018-03-01”等,则相同。但是当我使用“2018-01-01”时,我得到的不是“2017-12-01”,而是“2016-12-01”。

例如。假设 getdate() 带回“07/12/2018”,我需要的日期是上一年的上个月的第一天。所以它将是“06/01/2017”。对于“01/03/2018”,它将是“12/01/2017”。但我的声明带回了“2016 年 12 月 1 日”。

我的逻辑有什么问题?

SP 摘录如下:

SELECT c.ClientID ... 
INTO PC_Benefits_Expired 
from Client_Program cp 
INNER JOIN .... 
WHERE (CAST(cp.startdate AS DATE) >= CAST(DATEADD(year,-1,DATEADD(month, DATEDIFF(month, 0, getdate()), 0)) AS DATE) 
--OR 
--FirstDayOfCurrentMonthPriorYear CAST(cp.startdate AS DATE) >= CAST(DATEADD(year,-1,DATEADD(month, DATEDIFF(month, 0, getdate())-1, 0)) AS DATE)) 
--FirstDayOfLastMonthPriorYear and CAST(cp.EndDate AS DATE) <= CAST(DATEADD(day,-1,DATEADD(month, DATEDIFF(month, 0, GETDATE())+1, 0)) AS DATE) 
--LastDayOfCurrentMonthCurrentYear and CAST(cp.EndDate AS DATE)='2017-02-28'

【问题讨论】:

  • 您的逻辑有问题的是您当前的结果是正确的。 2018的上一年是2017,所以现在你站在2017年1月,上个月是2016年12月

标签: sql sql-server


【解决方案1】:

这是一种方法:

SELECT DATEADD(DAY,1,EOMONTH(GETDATE(),-2))

这将获取 2 个月前的最后一天,然后将其添加一天以提供一个月前的第一天。

你可以随意格式化:

SELECT FORMAT(DATEADD(DAY,1,EOMONTH(GETDATE(),-2)),'MM/dd/yyyy')

编辑:

对于已澄清的问题,您有两个单独的条件。我会使用 CASE 语句以不同方式处理一月条件:

SELECT CASE WHEN DATEPART(MONTH,GETDATE()) = 1
            THEN DATEADD(DAY,1,EOMONTH(GETDATE(),-2))
            ELSE DATEADD(YEAR,-1,DATEADD(DAY,1,EOMONTH(GETDATE(),-2)))
       END AS LastYearFirstOfPreviousMonthDATEADD

【讨论】:

  • 如何将它添加到我的 SP?
  • SELECT c.ClientID ... INTO PC_Benefits_Expired from Client_Program cp INNER JOIN .... WHERE (CAST(cp.startdate AS DATE) >= CAST(DATEADD(year,-1,DATEADD(month , DATEDIFF(month, 0, getdate()), 0)) AS DATE) 或 --FirstDayOfCurrentMonthPriorYear CAST(cp.startdate AS DATE) >= CAST(DATEADD(year,-1,DATEADD(month, DATEDIFF(month, 0 , getdate())-1, 0)) AS DATE)) --FirstDayOfLastMonthPriorYear 和 CAST(cp.EndDate AS DATE)
  • @DataCrypt 您的 SP 与 cmets 有点混淆,但如果我理解正确,您可以将上面的 CASE 语句复制粘贴到您的 WHERE 子句中。所以..WHERE (CAST(cp.startdate AS DATE) &gt;= insert case statement here
  • @DataCrypt 长话短说,只需将CASE 语句放在您当前拥有上一年、上个月的日期逻辑的任何位置。
【解决方案2】:

这应该可行:

SELECT CONVERT(CHAR(10),DATEADD(MONTH,DATEDIFF(MONTH, 0, getdate())-1,0),101)

【讨论】:

  • 谢谢,但我也需要将年份设为-1,这就是我遇到的问题。假设 getdate() 带回“07/12/2018”,我需要的日期是上一年上个月的第一天。所以它将是“06/01/2017”。对于“01/03/2018”,它将是“12/01/2017”。但我的声明带回了“2016 年 12 月 1 日”。您使用的是当前年份。
  • @DataCrypt 因为它真的没有意义......你需要上一年的前一个月......所以你当前的结果是正确的
  • 我在查询中使用它,我需要为在特定开始和结束日期(通常是过去一年)内注册的客户获取数据。运行查询/报告时,我使用当前月份并返回 1 年作为开始日期(StartDate >= .FirstDayOfCurrentMonthPriorYear 或 >= FirstDayOfLastMonthPriorYear)。结束日期
  • 我原来的 SQL 工作正常,但在一月份失败了,因为我得到了最后一个月(我需要它然后拿走我需要的那一年。在这种情况下拿走这个月份让我回来了到最后一年,然后我仍然要带走另一年,这把事情搞砸了。这就像我需要确定我是否在一月份而不是在我最初的帖子中执行 DATEADD(year, -1,...示例。我希望这是有道理的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多