【问题标题】:How to replace missing rows with the latest value from previous days in SQL?如何用 SQL 中前几天的最新值替换缺失的行?
【发布时间】:2019-09-16 13:00:30
【问题描述】:

这是我在这里向所有 Athena SQL 专家提出的第一个问题

我有一个 athena 数据库,其中包含一个包含过去 2 年用户数据的表。 此表以 parquet 格式存储在 S3 中,按日期(称为 dt 的列)分区。

表的每一行都包含用户 ID、时间戳、一些属性(prop1、prop2、prop3)和分区键 dt。

每天 (dt) 我每个用户都有零个、一个或多个条目。 我需要编写一个 Athena SQL 查询,输出过去 2 年的所有数据,每天 (dt) 都有最新的用户信息。 这意味着,如果最新的用户信息不存在于特定的 dt 中,我需要跨时间传播它。

示例输入表:

| dt |用户ID|时间戳 |p1 |p2 |p3 | |----------|------|------------|---|-- -|---| |01/09/2019| A |2019-09-01T09:50:04.082Z|x |y |z | |01/09/2019| A |2019-09-01T10:52:04.082Z|r |t |g | |01/09/2019| B |2019-09-01T11:02:04.082Z|a |s |d | |01/09/2019| C |2019-09-01T10:10:04.082Z|z |x |c | |----------|------|------------|---|-- -|---| |02/09/2019| B |2019-09-02T11:02:04.082Z|a |s |d | |----------|------|------------|---|-- -|---| |03/09/2019|一个 |2019-09-03T12:50:04.082Z|fd |swq|qw | |03/09/2019| B |2019-09-03T11:02:04.082Z|wre|ewr|我们 | |----------|------|------------|---|-- -|---| |04/09/2019| J |2019-09-04T11:02:04.082Z|dc |qw |w3 | |----------|------|------------|---|-- -|---| |05/09/2019| A |2019-09-05T11:02:04.082Z|qdw|qw |rg | |05/09/2019| B |2019-09-05T11:02:04.082Z|g |de |ew | |05/09/2019| J |2019-09-05T11:02:04.082Z|egr|gre|rg |

示例输出表:

| dt |用户ID|时间戳 |p1 |p2 |p3 | |----------|------|------------|---|-- -|---| |01/09/2019|一个 |2019-09-01T10:52:04.082Z|r |吨 |克 | |01/09/2019| B |2019-09-01T11:02:04.082Z|a |小号 | d | |01/09/2019| C |2019-09-01T10:10:04.082Z|z | x | c | |----------|------|------------|---|-- -|---| |02/09/2019| B |2019-09-02T11:02:04.082Z|a |小号 | d | |02/09/2019|一个 |2019-09-01T10:52:04.082Z|r |吨 |克 | |02/09/2019| C |2019-09-01T10:10:04.082Z|z | x | c | |----------|------|------------|---|-- -|---| |03/09/2019|一个 |2019-09-03T12:50:04.082Z|fd |swq|qw | |03/09/2019| B |2019-09-03T11:02:04.082Z|wre|ewr|我们 | |03/09/2019| C |2019-09-01T10:10:04.082Z|z | x |c | |----------|------|------------|---|-- -|---| |04/09/2019| J |2019-09-04T11:02:04.082Z|dc |qw |w3 | |04/09/2019|一个 |2019-09-03T12:50:04.082Z|fd |swq|qw | |04/09/2019| B |2019-09-03T11:02:04.082Z|wre|ewr|我们 | |04/09/2019| C |2019-09-01T10:10:04.082Z|z |x |c | |----------|------|------------|---|-- -|---| |05/09/2019| A |2019-09-05T11:02:04.082Z|qdw|qw |rg | |05/09/2019| B |2019-09-05T11:02:04.082Z|g |de |ew | |05/09/2019| J |2019-09-05T11:02:04.082Z|egr|gre|rg | |05/09/2019| C |2019-09-01T10:10:04.082Z|z |x |c | |----------|------|------------|---|-- -|---|

已编辑:

为了更容易尝试这里的方法,这里有一个查询来创建上表并从中选择所有项目:

WITH the_table AS ( SELECT '01/09/2019' AS dt, 'A' AS user_id, '2019-09-01T09:50:04.082Z' AS timestamp, 'x' as p1, 'y' as p2, 'z' as p3 UNION ALL SELECT '01/09/2019', 'A', '2019-09-01T10:52:04.082Z', 'r', 't', 'g' UNION ALL SELECT '01/09/2019', 'B', '2019-09-01T11:02:04.082Z', 'a', 's', 'd' UNION ALL SELECT '01/09/2019', 'C', '2019-09-01T10:10:04.082Z', 'z', 'x', 'c' UNION ALL SELECT '02/09/2019', 'B', '2019-09-02T11:02:04.082Z', 'a', 's', 'd' UNION ALL SELECT '03/09/2019', 'A', '2019-09-03T12:50:04.082Z', 'fd', 'swq', 'qw' UNION ALL SELECT '03/09/2019', 'B', '2019-09-03T11:02:04.082Z', 'wre', 'ewr', 'we' UNION ALL SELECT '04/09/2019', 'J', '2019-09-04T11:02:04.082Z', 'dc', 'qw', 'w3' UNION ALL SELECT '05/09/2019', 'A', '2019-09-05T11:02:04.082Z', 'qdw', 'qw', 'rg' UNION ALL SELECT '05/09/2019'、'B'、'2019-09-05T11:02:04.082Z'、'g'、'de'、'ew' UNION ALL SELECT '05/09/2019'、'J'、'2019-09-05T11:02:04.082Z'、'egr'、'gre'、'rg' 由 dt ASC 订购 ) 从 the_table 中选择 *

【问题讨论】:

  • 你已经尝试了什么?你研究过什么吗?
  • @Perazim 我已经尝试使用 LAG 的窗口化方法,但这并没有达到最终结果。

标签: sql amazon-athena


【解决方案1】:

我认为这其中的关键是MAX_BY 聚合函数。您所做的是按日期和用户 ID 分组,并在所有其他列上使用 MAX_BY,如下所示:

SELECT
  dt,
  user_id,
  MAX_BY(p1, timestamp) AS p1,
  MAX_BY(p2, timestamp) AS p2,
  -- etc.
FROM the_table
GROUP BY dt, user_id

MAX_BY 返回第二列具有最高值的组中第一列的值,即第一种情况下最高timestamp 值的p1 值。

【讨论】:

  • 有了这个我只会排除每个用户每天最旧的条目,但它不会为还没有条目的 dt 添加条目。
  • 你说得对,我一定是误解了你或者错过了这个要求。确保这一点的一种方法是创建不同日期和用户 ID 的叉积并将其加入以确保每个组合都有一行 - 但可能有更有效的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-30
  • 2013-01-17
  • 1970-01-01
  • 2021-09-28
  • 2021-10-25
相关资源
最近更新 更多