【问题标题】:Get total sales of last 12 months even if values are null即使值为空,也可以获得过去 12 个月的总销售额
【发布时间】:2020-07-07 10:45:14
【问题描述】:

我有以下代码,它目前给出了当年的每月总销售额,我需要得到从上一年最后一个月到今年当前月份的总销售额。

我的查询如下:

;WITH mcte AS (
 SELECT DATEADD(year, -1, getdate()) as MONTH_NAME
 UNION ALL
 SELECT DATEADD(MONTH,1,MONTH_NAME)
 FROM mcte
 WHERE DATEPART(MONTH,MONTH_NAME) < 12),octe AS(
 SELECT (DATENAME (MONTH, DATEADD ( MONTH, DATEPART(MONTH, OI.CreatedDate), -1) )) AS MONTH_NAME,
 SUM (OI.ItemQty * OI.TotalPrice) AS TOTAL_SALES
 FROM Order_Item OI            
 GROUP BY MONTH(OI.CreatedDate))
 SELECT DATENAME(MONTH,m.MONTH_NAME) + '' + DATENAME(YEAR,m.MONTH_NAME) as 
 MONTH_NAME, o.TOTAL_SALES FROM mcte m LEFT JOIN octe o ON o.MONTH_NAME = DATENAME(MONTH,m.MONTH_NAME)

我正在获取记录

MONTH_NAME     TOTAL_SALES
July2019       54023.45
August2019     NULL
December2019   NULL
September2019  NULL
October2019    NULL
November2019   NULL

这里我只获取前一年的数据,没有获取当前年份的数据。谁能指导我。

谢谢

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    您最多只能生成 12 个月。尝试将第一个 CTE 替换为:

    WITH mcte AS (
          SELECT DATEADD(year, -1, getdate()) as MONTH_NAME
          UNION ALL
          SELECT DATEADD(MONTH,1,MONTH_NAME)
          FROM mcte
          WHERE month_name < GETDATE()
         ),
    

    注意区别在于WHERE 子句。

    整个查询应该如下所示:

    WITH months AS (
          SELECT DATEFROMPARTS(YEAR(getdate()) - 1, MONTH(getdate()), 1) as month
          UNION ALL
          SELECT DATEADD(MONTH, 1, month)
          FROM months
          WHERE EOMONTH(month) < GETDATE()
         )
    SELECT m.month, SUM(OI.ItemQty * OI.TotalPrice) AS TOTAL_SALES
    FROM months m LEFT JOIN
         Order_Item OI oi
         ON oi.CreatedDate >= m.month AND
            oi.CreatedDate < DATEAADD(month, 1, m.month)          
    GROUP BY m.month
    

    【讨论】:

    • 很抱歉,它会将总销售额值与上一年月/当前年月中的任何一个给出空值
    • @ANALKUKADIA 。 . .很多事情需要修复。您的问题只是关于生成所有月份 - 而不是为特定数据集获取特定结果集。也就是说,我添加了您想要的查询。
    • 感谢您的解决方案,但它给了我一个错误“递归查询“mcte”的“月”列中的锚点和递归部分之间的类型不匹配。”
    • @ANALKUKADIA 。 . .我修复了递归 CTE,它可以工作:dbfiddle.uk/….
    【解决方案2】:

    尝试这样做:

    DECLARE @CurDate DATE = GET_DATE()
    DECLARE @OneYearPrior DATE = DATEADD(YEAR, -1, @CurDate)
    
    WITH relevant_months(start_date, month_of_sale, year_of_sale) AS (
        SELECT 
            @CurDate AS start_date, 
            MONTH(@CurDate) as month_of_sale, 
            YEAR(@CurDate) as year_of_sale
        UNION ALL
        SELECT DATEADD(MONTH, -1, start_date) AS start_date,
            MONTH(DATEADD(MONTH, -1, start_date)) as month_of_sale, 
            YEAR(DATEADD(MONTH, -1, start_date)) AS year_of_sale
        FROM relevant_months
        WHERE DATEADD(MONTH, -1, start_date) >= @OneYearPrior
    ),
    relevant_data AS (
        SELECT OI.CreatedDate, 
            OI.ItemQty, 
            OI.TotalPrice, 
            MONTH(OI.CreatedDate), AS month_of_sale, 
            YEAR(OI.CreatedDate) AS year_of_sale
        FROM Order_Item OI
        WHERE OI.CreatedDate >= DATEADD(YEAR, -1, GETDATE())
    )
    SELECT rm.month_of_sale as month, rm.year_of_sale as year, 
        SUM(rd.ItemQty*rd.TotalPrice) as total_sales
    FROM relevant_months rm
    LEFT JOIN relevant_data rd
        ON rm.month_of_sale = rd.month_of_sale
        AND rm.year_of_sale = rd.year_of_sale
    GROUP BY rm.month_of_sale, rm.year_of_sale
    ORDER BY rm.year_of_sale asc, rm.month_of_sale asc
    

    【讨论】:

    • 感谢您的解决方案,但在这里我还需要其他月份,包括空值。它仅显示具有值的月份
    • @rbolling 抱歉回复晚了。非常感谢您的解决方案,它有效.. 很好..
    • @ANALKUKADIA 太棒了!
    猜你喜欢
    • 2015-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-13
    • 2020-09-06
    • 2022-10-04
    • 2021-05-25
    相关资源
    最近更新 更多