匹配 Redshift SQL 中最近的时间戳
Posted
技术标签:
【中文标题】匹配 Redshift SQL 中最近的时间戳【英文标题】:Match nearest timestamp in Redshift SQL 【发布时间】:2021-12-05 12:13:08 【问题描述】:我有两张桌子,t1 和 t2。对于 t1 中的每个 id,我在 t2 中有多个记录。我想将 t2 的最近时间戳与 t1 的每条记录相匹配。在 t1 中有一个标志,如果它是 1,我想匹配 t2 的最接近的较小的时间戳,如果它是 0,我想匹配大于 t1 中的最接近的时间戳。 所以我总共有下表: T1 id、标志、时间戳 T2 id,时间戳
有没有有效的方法来做到这一点?
编辑,这里有一些例子:
T1
customer_id | timestamp_t1 | flag |
---|---|---|
1 | 01.01.21 12:00 | 1 |
2 | 01.01.21 13:00 | 0 |
T2
customer_id | timestamp_t2 | additional attributes |
---|---|---|
1 | 01.01.21 11:00 | attribute1 |
1 | 01.01.21 10:00 | attribute2 |
1 | 01.01.21 13:00 | attribute3 |
2 | 01.01.21 11:00 | attribute4 |
2 | 01.01.21 12:00 | attribute5 |
2 | 01.01.21 14:00 | attribute6 |
2 | 01.01.21 15:00 | attribute7 |
结果:
customer_id | timetsamp_t1 | timestamp_t2 | flag | additional attributes |
---|---|---|---|---|
1 | 01.01.21 12:00 | 01.01.21 11:00 | 1 | attribute1 |
2 | 01.01.21 13:00 | 01.01.21 14:00 | 0 | attribute6 |
我希望这会有所帮助。如你看到的。结果,我们将 T2 的 11:00 与 T1 的 12:00 匹配,因为标志为 1,我们选择了小于 12:00 的最接近的时间戳。我们还将 14:00 与 13:00 进行了匹配,因为标志为 0(因此我们匹配了 id 为 2 且大于 13:00 的最接近的时间戳)。
【问题讨论】:
提供样本数据和期望的结果会更有帮助 你需要table2的id还是时间戳?时间戳 table2 是否保证唯一? (这是示例数据和所需结果非常有用的一个示例。) 感谢您的建议。我添加了一个应该清楚的例子。我注意到这样解释会更好。 customer_id 在 T1 中是否唯一? T2 是否有id
列?
【参考方案1】:
您可以使用相关子查询来查找时间戳之前/之后的行,然后使用 CASE
表达式来选择要加入的行...
SELECT
*
FROM
t1
INNER JOIN
t2
ON t2.id = CASE WHEN t1.flag = 1 THEN
(
SELECT t2.id
FROM t2
WHERE t2.customer_id = t1.customer_id
AND t2.timestamp_t2 <= t1.timestamp_t1
ORDER BY t2.timestamp DESC
LIMIT 1
)
ELSE
(
SELECT t2.id
FROM t2
WHERE t2.customer_id = t1.customer_id
AND t2.timestamp_t2 >= t1.timestamp_t1
ORDER BY t2.timestamp ASC
LIMIT 1
)
END
哦,您的示例中没有包含 id
列,这同样适用...
SELECT
*
FROM
t1
INNER JOIN
t2
ON t2.customer_id = t1.customer_id
AND t2.timestamp_t2
=
CASE WHEN t1.flag = 1 THEN
(
SELECT MAX(t2.timestamp_t2)
FROM t2
WHERE t2.customer_id = t1.customer_id
AND t2.timestamp_t2 <= t1.timestamp_t1
)
ELSE
(
SELECT MIN(t2.timestamp_t2)
FROM t2
WHERE t2.customer_id = t1.customer_id
AND t2.timestamp_t2 >= t1.timestamp_t1
)
END
【讨论】:
嘿,非常感谢。这是一个简单的解决方案,我很惊讶。我想到了一个非常复杂的分区方法。我想知道这对于更大的数据集是否是最有效的方法。 @MiepMiep 分区将允许您在两个查询中使用 UNION ALL,而不是在单个查询中使用 CASE 表达式。如果您想询问有关重塑数据的问题,您应该在问题中说明(提供完整的 DDL、有关数据量、基数等的详细信息)。以上是关于匹配 Redshift SQL 中最近的时间戳的主要内容,如果未能解决你的问题,请参考以下文章