MySQL присоединение самой последней строки во внешней таблице для каждой строки - PullRequest
0 голосов
/ 30 марта 2020

У меня есть 2 таблицы, одна из локаций (сборка, метка времени и позиция) и одна из изменений статуса (асситид, метка времени и статус). Я пытаюсь выбрать все местоположения, присоединенные к «текущему состоянию», которое определяется самым последним изменением статуса до отметки времени позиции (status.timestamp <= location.timestamp). </p>

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 () ниже действительно решает проблему, но не эффективно. Выполнение запроса на моем полном наборе данных, и время ожидания истекло. Есть ли другой подход к этой проблеме?

1 Ответ

1 голос
/ 30 марта 2020

В 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...