【问题标题】:get last 3 month on year in sql server在 sql server 中获取去年的最后 3 个月
【发布时间】:2016-03-06 12:47:34
【问题描述】:

我想从当前月份获取最近 3 个月的名称。例如,当前月份是 12 月。所以,我想像这个十月、十一月和十二月一样。

这是我的查询:

SELECT CONVERT(CHAR, DATENAME(MONTH, IssueDate)) AS MonthName, ItemId
FROM dbo.Issue AS Issue
GROUP BY CONVERT(CHAR, DATENAME(MONTH, IssueDate)), ItemId
HAVING (ItemId = 427)

这会返回:

但是,我的需要是:

注意当 12 月关闭和 1 月打开时,10 月自动排除(11 月、12 月和 1 月)

此链接是我在 Google 驱动器上的仅数据库 2 表(大小为 243 KB,带 Zip) https://goo.gl/S4m0R5

【问题讨论】:

    标签: sql sql-server sql-server-2008 sql-server-2005


    【解决方案1】:

    在 where 子句中添加日期差异以过滤到最近 3 个月,然后在末尾按月份编号排序:

    SELECT CONVERT(CHAR, DATENAME(MONTH, [IssueDate])) AS MonthName, ItemId
    FROM  [dbo].[Issue] AS Issue
    WHERE datediff(m, [IssueDate], getdate()) between 0 and 2
    GROUP BY CONVERT(CHAR, DATENAME(MONTH, [IssueDate])), ItemId, MONTH(IssueDate)
    HAVING (ItemId= 427)
    order by MONTH(IssueDate);
    

    【讨论】:

      【解决方案2】:

      您可以使用 DATEADD 功能:

      WHERE IssueDate >= dateadd( month, -2, dateadd( day, -datepart( day, getdate() ) + 1, cast( getdate() as date ) ) )
      

      这将为您提供今天给出的 IssueDate >= '2015-10-01'。

      这也适用于您在 IssueDate 上拥有的索引,如果您开始在 IssueDate 上执行 DATEADD / DATEDIFF 等操作,则只能端到端扫描索引,因为它需要处理表中的所有行,所以使索引的效果显着降低。

      【讨论】:

        【解决方案3】:
        DECLARE @t TABLE
        (
            IssueDate DATETIME,
            ItemId INT
        )
        
        INSERT INTO @t (IssueDate, ItemId)
        VALUES
            ('20160105', 427),
            ('20151212', 427),
            ('20151213', 427),
            ('20151110', 427),
            ('20151001', 427),
            ('20150905', 427)
        
        SELECT DATENAME(MONTH, dt)
        FROM (
            SELECT DISTINCT TOP(3) DATEADD(MONTH, DATEDIFF(MONTH, 0, IssueDate), 0) AS dt
            FROM @t
            WHERE ItemId = 427
            ORDER BY dt DESC
        ) t
        

        结果 -

        ------------------------------
        January
        December
        November
        

        【讨论】:

        【解决方案4】:

        您可以使用递归 CTE 获取过去 12 个月的月份名称,然后在查询的第二部分将其限制为最近 3 个月的名称:

        ;WITH months(MonthNumber) AS
        (
           SELECT 0
           UNION ALL
           SELECT MonthNumber+1 
           FROM months
           WHERE MonthNumber < 12
        )
        SELECT DATENAME(MONTH,DATEADD(MONTH,-MonthNumber,GETDATE())) AS [month]
        FROM dbo.Issue AS Issue
        CROSS JOIN months m
        WHERE m.MonthNumber <3
        GROUP BY DATENAME(MONTH,DATEADD(MONTH,-MonthNumber,GETDATE())) , ItemId
        HAVING (ItemId = 427)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-07-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多