mysql - MySQL为每一行加入外部表中的最新行
问题描述
我有 2 个表,其中一个是位置(assetid、时间戳和位置),另一个是状态更改(assitid、时间戳和状态)。我正在尝试选择所有位置,加入“当前状态”,该状态由位置时间戳之前的最新状态更改确定(status.timestamp <= location.timestamp)。
Locations
ID Asset Timestamp Lat/Lon
1 A 1000 Lat/Lon
2 A 2000 Lat/Lon
3 A 3000 Lat/Lon
Status
ID Asset Timestamp Status
1 A 1000 active
2 A 2200 sleep
我在找什么:
LocID Asset Timestamp Lat/Lon Status
1 A 1000 Lat/Lon active
2 A 2000 Lat/Lon active
3 A 3000 Lat/Lon sleep
我知道“加入最近一行”问题已被问了 1000 次,但我对这个问题的解决方案在这里不起作用。在这种情况下,我不只是在寻找最近的行,我需要相对于位置表中的时间戳的最新状态......这超出了我的能力范围。
MariaDB 10.4.12
在此先感谢您的帮助!
编辑:下面使用 row_number() 的建议确实解决了问题,但效率不高。在我的完整数据集上运行查询,它超时。有没有另一种方法来解决这个问题?
解决方案
在 MySQL 8.x 中,您可以使用ROW_NUMBER()
窗口函数来过滤相关行。
例如:
select loc_id, asset, timestamp
from (
select
l.id as loc_id,
l.asset,
l.timestamp,
row_number() over(partition by l.asset order by s.timestamp desc) as rn
from locations l
join status s on s.asset = l.asset and s.timestamp <= l.timestamp
) x
where rn = 1
whiteatom 编辑: 为了未来的读者 - 这行得通。我只需要更改分区(重新开始编号;就像分组一样)。一旦我将其更改为“按 l.asset、l.timestamp 分区”,它就会在每个新位置的时间戳重新开始编号,并且编号为 1 的行都是正确的。
工作示例:
select loc_id, lts, asset, location, status
from (
select
l.id as loc_id,
l.asset,
l.timestamp as lts,
l.location,
s.status,
row_number() over(partition by l.asset, l.timestamp order by s.timestamp desc) as rn
from location l
join status s on s.asset = l.asset and s.timestamp <= l.timestamp
) x
where rn = 1
推荐阅读
- android - Android 如何将 setOnEditorActionListener 添加到 EditTexts 列表
- html - 不能在同一行设置 div
- ansible - 将 bash 转换为 ansible - 替换包含单词的行
- server - jmeter如何开始向服务器发送请求
- azure - 通过 API 触发 Azure Pipelines 构建
- sitefinity - 要传递以获取 dec 交互的默认数据源名称是什么?
- php - CakePHP 3.6:计算表中不同的记录
- javascript - 通过 AJAX 函数循环 - 导致无限循环
- c++ - 模板指针作为成员
- testing - 在具有 `MAIN` 定义的模块上使用 `use-ok` 进行测试