【问题标题】:Dealing with required duplicates in table records处理表记录中所需的重复项
【发布时间】:2020-10-02 20:31:00
【问题描述】:

情况是这样的。我的团队以每月一次的分辨率预测销售和收入数字,但希望所有报告都以每日一次的分辨率进行。所以我正在做的是摄取这些数字并将每月目标除以天数并将其保存在表格中。 所以我从这样的事情开始:

| date    | forecasted_units | forecasted_revenue |
|---------|------------------|--------------------|
| 2020-01 | 372              | 9300               |
| 2020-02 | 435              | 9280               |
...

我的目标表现在看起来像这样:

| date       | forecasted_units | forecasted_revenue |
|------------|------------------|--------------------|
| 2020-01-01 | 12               | 300                |
| 2020-01-02 | 12               | 300                |
| 2020-01-03 | 12               | 300                |
...
| date       | forecasted_units | forecasted_revenue |
|------------|------------------|--------------------|
| 2020-02-01 | 15               | 320                |
| 2020-02-02 | 15               | 320                |
| 2020-02-03 | 15               | 320                |
...

现在我的表比上面的要宽很多,而且所有的表都有重复的记录。如您所见,存在大量数据冗余。现在我的问题是,有没有一种更有效的方法可以将相同分辨率的数据保存在一个表中。

我的直接想法是重塑表格以包含开始日期和结束日期,如下所示:

| start_date | end_date   | forecasted_units | forecasted_revenue |
|------------|------------|------------------|--------------------|
| 2020-01-01 | 2020-01-31 | 12               | 300                |
| 2020-02-01 | 2020-02-29 | 15               | 320                |

但这会将所有计算卸载到生成所有报告的实例,因为它必须为开始日期和结束日期之间的每一天生成数据。

有没有更好的方法来做到这一点?

【问题讨论】:

    标签: sql date amazon-redshift window-functions recursive-query


    【解决方案1】:

    不幸的是,Redshift 不支持方便的 Postgres 函数generate_series(),这将大大简化这里的任务。

    典型的替代解决方案将涉及一个日历表 - 基本上是一个枚举所有可能日期的表。如果您有一个包含足够行数的表,您可以使用row_number()dateadd() 即时生成这样的数据集:

    select dateadd(day, row_number() over(order by 1) - 1, '2020-01-01') dt
    from my_large_table;
    

    您可以将结果存储在另一个表中(使用create table ... as select ... 语法),或直接使用查询结果。在这两种情况下,您都可以将它与您的实际表连接起来。要计算一个月的天数,我们使用窗口计数:

    select
        d.dt,
        t.forecasted_unit    / count(*) over(partition by t.date) forecasted_units,
        t.forecasted_revenue / count(*) over(partition by t.date) forecasted_revenue
    from (
        select dateadd(day, row_number() over(order by 1) - 1, '2020-01-01') dt
        from my_large_table
    ) d
    inner join mytable t on t.date = date_trunc('month', d.dt)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-25
      • 1970-01-01
      • 2017-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多