【问题标题】:Calculate the monthly average including the date where data is missing计算包括数据缺失日期在内的月平均值
【发布时间】:2020-12-04 02:25:52
【问题描述】:

我想使用 SQL 查询计算某些数据的月平均值,其中数据位于 redshift DB 中。 数据在表格中以下列格式显示。

   s_date   | sales 
------------+-------
 2020-08-04 |    10
 2020-08-05 |    20
   ----     |    --
   ----     |    --

数据可能不会出现在一个月中的所有日期。 如果某天数据不存在,则应视为 0。
以下查询使用 AVG() 函数“分组”月份作为基于可用日期数据的平均值。

select trunc(date_trunc('MONTH', s_date)::timestamp) as month, avg(sales) from sales group by month;

但它不会将缺失日期的数据视为 0。按预期计算每月平均值的正确查询应该是什么?

另一个期望是,对于当前月份,应根据截至今天的数据计算平均值。所以它不应该考虑整个月(比如 30 或 31 天)。

问候,
保罗

【问题讨论】:

    标签: sql amazon-redshift


    【解决方案1】:

    使用日历表可能是最简单的方法:

    WITH dates AS (
        SELECT date_trunc('day', t)::date AS dt
        FROM generate_series('2020-01-01'::timestamp, '2020-12-31'::timestamp, '1 day'::interval) t
    ),
    cte AS (
        SELECT t.dt, COALESCE(SUM(s.sales), 0) AS sales
        FROM dates t
        LEFT JOIN sales s ON t.dt = s.s_date
        GROUP BY t.dt
    )
    
    SELECT
        LEFT(dt::text, 7) AS ym,
        AVG(sales) AS avg_sales
    FROM cte
    GROUP BY
        LEFT(dt::text, 7);
    

    这里的逻辑是首先在第二个 CTE 中生成一个中间表,其中包含您数据集中的每个数据的一条记录,以及该日期的总销售额。然后,我们按年/月汇总,并报告平均销售额。

    【讨论】:

    • generate_series() 不起作用,因为数据处于红移状态。因此必须以不同的方式生成日期系列。但是这里给出的逻辑确实有效。
    • @Paul 经验教训:不要使用错误的数据库进行标记。唯一需要更改的部分是 CTE 日期。搜索如何在 Redshift 中创建日历表。
    • 我已经弄清楚如何生成日期 CTE。关于标签,目的是在 Redshift 或 Postgres 中获取逻辑。如果逻辑清楚,那么我认为在redshift中实现同样的并不难。你的回答就是一个例子。
    • @Paul 仅供参考,Redshift 基于旧版本 Postgres 的一些分支,因此我的大多数(但不是全部)Postgres 答案已经在工作了。
    • @Paul 。 . .您接受了一个实际上并没有回答问题的答案。您可能希望将此问题的标签还原为 Postgres 并提出一个新问题。
    猜你喜欢
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-24
    • 1970-01-01
    • 2019-06-23
    • 1970-01-01
    • 2019-01-06
    相关资源
    最近更新 更多