匹配 Redshift 中最近的时间戳 SQL
Match nearest timestamp in Redshift SQL
我有两个 table,t1 和 t2。对于 t1 中的每个 id,我在 t2 中有多个记录。我想将 t2 的最接近时间戳与 t1 的每条记录相匹配。在 t1 中有一个标志,如果它是 1,我想匹配更小的 t2 的最近时间戳,如果它是 0,我想匹配比 t1 中的时间戳最近的时间戳。
所以我总共有以下 table:
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(因此我们将最接近的时间戳与大于 13:00 的 id 2 匹配)。
您可以使用相关子查询来查找行 before/after 时间戳,然后使用 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
我有两个 table,t1 和 t2。对于 t1 中的每个 id,我在 t2 中有多个记录。我想将 t2 的最接近时间戳与 t1 的每条记录相匹配。在 t1 中有一个标志,如果它是 1,我想匹配更小的 t2 的最近时间戳,如果它是 0,我想匹配比 t1 中的时间戳最近的时间戳。 所以我总共有以下 table: 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(因此我们将最接近的时间戳与大于 13:00 的 id 2 匹配)。
您可以使用相关子查询来查找行 before/after 时间戳,然后使用 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