【问题标题】:Join tables with nearest timestamp以最近的时间戳连接表
【发布时间】:2020-05-26 23:05:15
【问题描述】:

我有两个表,我需要用最近的时间戳将它们连接起来,但我找不到简单的 SQL 方法。

示例数据:

table_1
+---------------------+------+
|      timestamp      | name |
+---------------------+------+
| 2020-02-11 14:50:00 | xxx  |
| 2020-02-11 14:51:00 | yyy  |
| 2020-02-11 14:52:00 | zzz  |
+---------------------+------+
table_2
+---------------------+-------+
|      timestamp      | value |
+---------------------+-------+
| 2020-02-11 14:49:50 |     1 |
| 2020-02-11 14:49:58 |     2 |
| 2020-02-11 14:49:59 |     3 |
| 2020-02-11 14:50:50 |    11 |
| 2020-02-11 14:50:58 |    12 |
| 2020-02-11 14:50:59 |    13 |
| 2020-02-11 14:51:50 |    21 |
| 2020-02-11 14:51:58 |    22 |
| 2020-02-11 14:51:59 |    23 |
+---------------------+-------+

我需要让table_1 left join table_2 与最近的时间戳,条件是table_2 中的时间戳总是比table_1 中的小一点。有了这个逻辑,我期待得到这个结果表。

expected result
+---------------------+------+-------+
|      timestamp      | name | value |
+---------------------+------+-------+
| 2020-02-11 14:50:00 | xxx  |     3 |
| 2020-02-11 14:51:00 | yyy  |    13 |
| 2020-02-11 14:52:00 | zzz  |    23 |
+---------------------+------+-------+

我是否可以使用 SQL 查询来完成它,即使它可能效率不高?否则,我正在考虑加载数据以触发数据框。我们在 spark 中实现了这种算法吗?

谢谢

【问题讨论】:

  • 是的,您可以通过查询来完成。效率不是问题
  • 谢谢,但是怎么做?我想不明白。你有例子吗?
  • 请自行决定要使用什么环境(mysqapache-spark)和edit 相应的问题。这是两个不同的系统,具有不同的支持功能和不兼容的 SQL 方言。

标签: mysql sql dataframe apache-spark dataset


【解决方案1】:

如果您只需要来自table_2value,我会使用 Gordon 的答案。但如果您需要选择更多列,我会在 LEFT JOINs ON 子句中使用相关子查询:

select t1.timestamp, t1.name, t2.value
from table_1 t1
left join table_2 t2 on t2.timestamp = (
  select max(t2i.timestamp)
  from table_2 t2i
  where t2i.timestamp <= t1.timestamp
)

结果:

| timestamp           | name | value |
| ------------------- | ---- | ----- |
| 2020-02-11 14:50:00 | xxx  | 3     |
| 2020-02-11 14:51:00 | yyy  | 13    |
| 2020-02-11 14:52:00 | zzz  | 23    |

View on DB Fiddle

【讨论】:

  • 为什么是左连接?
  • @Strawberry 等一下.... LEFT JOIN 因为 OP 明确要求:“我需要让 table_1 左连接 table_2”。
  • 我怀疑 OP 不知道他们在说什么 - 想在这里返回空结果似乎很奇怪(但当然我可能完全错了)
  • @Strawberry 我不知道真正的任务是否需要 LEFT JOIN - 但显然可能有原因。如果您想要来自t1 的所有行,而不管t2 中是否存在较小的时间戳 - 您需要一个左连接。如果 JOIN 未找到匹配项,则结果中只有 value 列将为 NULL。
【解决方案2】:

您可以使用相关子查询:

select t1.*,
       (select t2.value
        from table_2 t2
        where t2.timestamp <= t1.timestamp
        order by t2.timestamp desc
        limit 1
       ) as t2_value
from table_1 t1;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-31
    • 2020-06-17
    相关资源
    最近更新 更多