【问题标题】:SQL Server : average sales with Date Range CriteriaSQL Server:使用日期范围标准的平均销售额
【发布时间】:2017-04-21 00:18:04
【问题描述】:

我是 SQL Server 的新手(比如 10 分钟)。我有一个包含几列(单位、日期、主 ID、AVE 月销售额)的测试数据库。平均每月销售额为空。

背景:我从 Excel 文件中导入数据,这些文件是从其他文件构建的,平均销售计算时间是 Excel 让我抓狂,因此这篇文章。

我想做的是根据相关行中的日期用过去 6 个月的平均单位数填充平均销售额列。即如果日期是 2016 年 6 月 31 日,我应该获得从 2016 年 1 月 1 日到包括 2016 年 6 月 31 日的特定主 ID 的平均单位销售额(主 ID 不是我的唯一密钥 - 仅供参考) .

如前所述,我是 SQL 新手,我使用的是 SQL Server Express(本地运行),数据表 (SALES) 大约有 8m 行。我不确定这样的计算是否应该使用 SQL,但我想尝试一下,以便检查它是否比我目前的方法(Excel)更快。

如果有人能举例说明这一点,那就太好了。

谢谢。 标记。

【问题讨论】:

  • 您运行的是什么版本的 Express(2008、2012、2014 等)?
  • 嗨 Rich,我使用的是 2016
  • 您是否需要将此数据保留在表中,还是仅在拉取数据时才需要此新列(以便您可以在查询中计算它)?
  • 我想把这个放在桌子上。 (已编辑)
  • 你有一个独特的列吗?

标签: sql sql-server date average sql-server-2016-express


【解决方案1】:

用你的主键列替换一些唯一字段,也只用选择先测试它。

UPDATE t SET [AVE Monthly Sales] = x.avgsum FROM table t JOIN
(SELECT someuniquefield ,
  AVG(CASE WHEN date > DATEADD(m, -6, date - DATEPART(d, date) + 1) THEN Units END) OVER (ORDER BY Date DESC) avgsum 
    FROM table  ) as x
ON x.someunqiuefield.=t.someuniquefield

【讨论】:

    【解决方案2】:

    我假设您希望它是动态的而不是固定的值(以允许修改数据并显示正确的值)。下面的示例显示了我将如何在 SELECT 查询中执行此操作(不修改基础数据);

    测试数据(# = 临时表)

    CREATE TABLE #TestTable (Units int, Date_Field datetime, Master_ID int)
    INSERT INTO #TestTable (Units, Date_Field, Master_ID)
    VALUES
     (10,'2016-07-06',1)
    ,(20,'2016-08-06',1)
    ,(30,'2016-09-06',1)
    ,(40,'2016-10-06',1)
    ,(50,'2016-11-06',1)
    ,(60,'2016-12-06',1)
    ,(70,'2016-10-06',2)
    ,(80,'2016-11-06',2)
    ,(90,'2016-12-06',2)
    

    查询

    SELECT
         tt.Master_ID
         ,tt.Date_Field
         ,tt.Units
         ,SUM(tt2.Units) Sum_Units
    FROM #TestTable tt
    LEFT JOIN #TestTable tt2
        ON tt2.Date_Field BETWEEN DATEADD(m,-3,tt.Date_Field) AND tt.Date_Field
        AND tt.Master_ID = tt2.Master_ID
    GROUP BY tt.Master_ID, tt.Date_Field, tt.Units
    ORDER BY tt.Master_ID, tt.Date_Field
    

    输出

    Master_ID   Date_Field                  Units   Sum_Units
    1           2016-07-06 00:00:00.000     10      10
    1           2016-08-06 00:00:00.000     20      30
    1           2016-09-06 00:00:00.000     30      60
    1           2016-10-06 00:00:00.000     40      90
    1           2016-11-06 00:00:00.000     50      120
    1           2016-12-06 00:00:00.000     60      150
    2           2016-10-06 00:00:00.000     70      70
    2           2016-11-06 00:00:00.000     80      150
    2           2016-12-06 00:00:00.000     90      240
    

    这里的逻辑是,您要重新加入日期范围为 -3 个月的同一张表(对于本示例),以提供您的运行总计。

    这样做会更容易,而不是尝试将数据保存在计算列中(这将是我的另一种方法),因为您只需在提取数据时运行一次。每次您将任何数据放入此表时,计算列都必须进行计算。

    【讨论】:

    • 您好 Rich,感谢您的详细回复,我将尝试您所做的一切,我会尽快回复您。
    猜你喜欢
    • 2013-09-28
    • 2019-07-17
    • 1970-01-01
    • 2016-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多