【问题标题】:SQL : automatically fill price between datesSQL:自动填充日期之间的价格
【发布时间】:2020-06-09 07:39:03
【问题描述】:

我正在尝试从两个表中编写一个视图,一个包含产品 ID 和周的参考表:

+------------+------+
| Product_id | week |   t1
+------------+------+
|          1 |    1 |
|          2 |    1 |
|          1 |    2 |
|          2 |    2 |
|          1 |    3 |
|          2 |    3 |
+------------+------+ etc...

另一个包含产品 ID、产品价格变化的周数和价格

+------------+------+-------+
| Product_id | week | price | t2
+------------+------+-------+
|          1 |    1 |    70 |
|          1 |    2 |    50 |
|          2 |    2 |    70 |
|          1 |    4 |    30 |
|          2 |    4 |    40 |
+------------+------+-------+

我知道如何通过加入这两个表来轻松实现这一点:

+------------+------+-------+
| Product_id | week | price | 
+------------+------+-------+
|          1 |    1 |    70 |
|          1 |    2 |    50 |
|          1 |    3 |       |
|          1 |    4 |    30 |
|          1 |    5 |       |
|          2 |    1 |       |
|          2 |    2 |    70 |
|          2 |    3 |       |
|          2 |    4 |    40 |
|          2 |    5 |       |
+------------+------+-------+

但我的目标是填补空白并获得每周的价格(不创建任何新表),例如:

+------------+------+-------+
| Product_id | week | price |
+------------+------+-------+
|          1 |    1 |    70 |
|          1 |    2 |    50 |
|          1 |    3 |    50 |
|          1 |    4 |    30 |
|          1 |    5 |    30 |
|          2 |    1 |       |
|          2 |    2 |    70 |
|          2 |    3 |    70 |
|          2 |    4 |    40 |
|          2 |    5 |    40 |
+------------+------+-------+ (product 2 isn't sold yet at week 1, so it doesn't have a price).

我不知道如何在 SQL 中执行此操作。我还没有使用 PARTITION BY 或 LAG ,这可能是我正在寻找的。如果有人能把我推向正确的方向,我将不胜感激:)

【问题讨论】:

    标签: sql select teradata window-functions


    【解决方案1】:

    您可以使用窗口函数 - teradata 支持的 ignore nulls 子句在这里派上用场:

    select
        t1.product_id,
        t1.week,
        coalesce(
            t2.price,
            lag(t2.price ignore nulls) over(partition by t1.product_id order by t1.week)
        ) price
    from t1
    left join t2 
        on  t2.product_id = t1.product_id
        and t2.week = t1.week
    

    或者更好的是,正如 dnoeth 所建议的,您可以使用last_value(),这样就不需要coalesce()

    select
        t1.product_id,
        t1.week,
        last_value(t2.price ignore nulls) over(partition by t1.product_id order by t1.week) price
    from t1
    left join t2 
        on  t2.product_id = t1.product_id
        and t2.week = t1.week
    

    【讨论】:

    • 无需 COALESCE/LAG:last_value(t2.price ignore nulls) over(partition by t1.product_id order by t1.week)
    • @dnoeth:是的,好点,这更简单。答案已更新 - 有学分。谢谢!
    【解决方案2】:

    使用cross join 生成行,然后使用left join 和窗口函数:

    with weeks as (
          select row_number() over (order by product_id) as n
          from table1
         )
    select t1.product_id, w.n as week,
           coalesce(t2.price, lag(t2.price ignore nulls) over (partition by p.product_id order by w.n)
                   ) as price
    from (select distinct product_id
          from table1 t1
         ) p cross join
         weeks w left join
         table2 t2
         on t2.product_id = p.product_id and t2.week = w.week
    where w.n <= 5
    

    【讨论】:

      【解决方案3】:

      您可以使用LEFT JOIN 来完成此操作。

      SELECT t1.Product_id, t1.week, tmp.price
      FROM t1
      LEFT JOIN t2 tmp ON tmp.Product_id = t1.Product_id AND
                          tmp.week = (SELECT MAX(week) FROM t2
                                      WHERE Product_id = tmp.Product_id AND week <= t1.week)
      ORDER BY t1.Product_id, t1.week
      

      我认为OUTER APPLY 会更干净,但我不知道 teradata 是否支持。

      SELECT t1.Product_id, t1.week, oa.price
      FROM t1
      OUTER APPLY (SELECT TOP 1 price FROM t2
                   WHERE Product_id = t1.Product_id AND week <= t1.week
                   ORDER BY week DESC) oa
      ORDER BY t1.Product_id, t1.week
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-05
        • 2014-11-04
        • 2019-07-20
        • 1970-01-01
        • 1970-01-01
        • 2020-11-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多