【问题标题】:SQL Server getting last X month average including missing monthsSQL Server 获得最近 X 个月的平均值,包括缺失的月份
【发布时间】:2018-04-20 14:01:23
【问题描述】:

我每月的销售数据是这样的。(希望我可以画桌子,但它不让我放一张或者我不知道如何)

表格有两列日期和销售单位。日期只有一个月的第一天。但并非所有月份都有条目。所以它可能是 2017 年 3 月 1 日有 20 个单位。然后 2017 年 4 月 1 日没有行。 2017 年 5 月 1 日有 100 个单位。

例如,我需要计算过去 3 个月的平均值。但是有几个月没有排。我如何将缺失的月份包括在平均计算中?我可以进行分组和平均,但这会在计算中忽略缺失的月份。

提前致谢。

【问题讨论】:

  • 只需将在该范围内销售的单位数量相加,然后除以您需要的月数。不用担心错过几个月
  • 您的 SQL 服务器版本是多少?
  • 你可以在这里画你的桌子:tablesgenerator.com/text_tables 并把生成的ascii放在问题中
  • 创建一个包含所有月份的单独表格(或创建一个动态视图)并将LEFT JOIN它添加到您的表格中。
  • 搜索有关构建和使用日历表的一些信息。这是你会一次又一次地回来的东西。这是一个帮助您入门的链接。不过,那里有相当多的工作。 stackoverflow.com/questions/5635594/…

标签: sql-server group-by average


【解决方案1】:
-- reference date to start data aggregation
declare @refDate date = '2017-04-27'
-- number of months to go back    
declare @LastMonthsN int = 3

如果您需要显示最近 n 个月的所有行:

;with
m as (
    select DATEADD(mm, DATEDIFF(mm, 0, @refdate)-_month+1, 0) _month
    from ( values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12)) x (_month)
    where _month<=@LastMonthsN
),
f as (
    select *
    from SalesData d
    where ref_month between dateadd(mm, -@LastMonthsN, @refDate) and dateadd(mm, 0, @refDate)
)
select _month, Isnull(qty, 0) qty
from m
left join f on _month = ref_month

如果你只需要周期平均值:

;with
f as (
    select *
    from SalesData d
    where ref_month between dateadd(mm, -@LastMonthsN, @refDate) and dateadd(mm, 0, @refDate)
)
select avg(isnull(qty, 0)) periodAVG
from f 

【讨论】:

    【解决方案2】:

    您可以创建一个包含所有月份的 cte,然后加入它。任何没有数据的月份都将为空,因此如果您发现计算不正确,则可能需要将其 ISNULL() 设为 0。

    ;with months AS (
    SELECT CAST('2017-01-01' AS DATE) AS month_
    UNION ALL
    SELECT DATEADD(MONTH, 1, month_) 
    FROM months
    WHERE month_ <'2017-12-01'
    )
    
    SELECT 
    DATEPART(QUARTER, m.month_) AS sale_quarter, --should be fine in SQL Server 2008
    SUM(units_sold) AS units_sold
    
    FROM months m
    
    LEFT JOIN your_sales_table s
        ON s.date = m.month_
    
    GROUP BY DATEPART(QUARTER, m.month_)
    

    如果您需要自定义 3 个月范围而不是正常季度,只需稍作更改即可。

    SELECT 
    SUM(units_sold) AS units_sold
    
    FROM months m
    
    LEFT JOIN your_sales_table s
        ON s.date = m.month_
    
    WHERE m.month_ IN ('2017-03-01','2017-04-01','2017-05-01')
    

    【讨论】:

      猜你喜欢
      • 2018-09-01
      • 1970-01-01
      • 2022-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多