我有一个简单的表,其中包含一年中产品及其每天总销售额的记录(只有3列-产品、日期、销售额)。所以,举个例子,如果产品a每天都有销售,它就有 365
记录。同样地,如果产品b只卖50天,那么这个表就只有 50
该产品的行-每销售一天一行。
我需要计算全年的日均销售额和标准差,这意味着,对于产品b,我需要额外的 365-50=315
销售为零的分录能够正确计算年度的日平均值和标准差。
有没有一种方法可以在sql中高效、动态地实现这一点?
谢谢
我有一个简单的表,其中包含一年中产品及其每天总销售额的记录(只有3列-产品、日期、销售额)。所以,举个例子,如果产品a每天都有销售,它就有 365
记录。同样地,如果产品b只卖50天,那么这个表就只有 50
该产品的行-每销售一天一行。
我需要计算全年的日均销售额和标准差,这意味着,对于产品b,我需要额外的 365-50=315
销售为零的分录能够正确计算年度的日平均值和标准差。
有没有一种方法可以在sql中高效、动态地实现这一点?
谢谢
3条答案
按热度按时间s3fp2yjn1#
我们可以生成366行,并将销售数据连接到其中:
您可以用例如。
AVG(COALESCE(numsales, 0))
. 您可能还需要一个where子句来消除非闰年的366天(例如将年份除以4,如果是0,则只执行366行)。如果你只做了一年,你可以在sales子查询中使用where子句只给出相关的记录;最有效的方法是使用
WHERE salesdate >= DATEFROMPARTS(YEAR(GetDate()), 1, 1) AND salesdate < DATEFROMPARTS(YEAR(GetDate()) + 1, 1, 1)
而不是在每个销售日期调用函数,从中提取年份以与常量进行比较。如果只有一年,您还可以从select/group by中删除年份(salesdate)如果你做了很多年,你可以让rg生成更多的行,或者(也许更简单)交叉连接到一个年份列表,这样你就得到366行乘以例如。
VALUES (2015),(2016),(2017),(2018),(2019),(2020)
(并从销售部分加入年份)mwngjboj2#
找到一年中的第一天和最后一天,然后使用
datediff()
找到当年的天数。在那之后不要使用
AVG
关于销售,但是SUM(Sales) / days_in_year
```select *,
days_in_year = datediff(day, first_of_year, last_of_year) + 1
from (values (2019), (2020)) v(year)
cross apply
(
select first_of_year = dateadd(year, year - 1900, 0),
last_of_year = dateadd(year, year - 1900 + 1, -1)
) d
3duebb1j3#
有一个不同的方法来看待它-不要试图添加额外的空行,只是除以一年中的天数。虽然一年的天数不是恒定的(闰年有366天),但由于一年的第一天总是1月1日,最后一天总是12月31日,因此可以很容易地计算: