2012-05-22 3 views
2

Я имею дело с некоторыми слегка завинчивыми данными в MySQL (5.5). У меня есть таблица, которая используется для отслеживания обоих статусов (новых, активных, неактивных и т. Д.) И изменений «местоположения», где местоположение имеет формат x.0.y, причем x и y являются целыми положительными.Приоритеть левой строки join в MySQL

Я пытаюсь переместить изменения местоположения в отдельную таблицу, но для этого мне нужно восстановить полное старое местоположение из других записей в таблице. Полное старое местоположение не сохраняется в записях изменения местоположения, как вы можете увидеть ниже:

id  status  new_loc  timestamp 
--  ------  -------  --------- 
5  1 -> 1  1.0.2  2012-05-21 00:00:00 
5  new   1.0.1  2012-05-21 00:00:03 
5  1 -> 2  2.0.1  2012-05-22 00:00:00 
5  2 -> 3  3.0.1  2012-05-23 00:00:00 

Таким образом, при изменении местоположения происходит, все, что записано в полной мере новое место и первая часть старого местоположение (слева от сообщения о состоянии). Тем не менее, я могу посмотреть предыдущие записи, чтобы найти полное старое местоположение.

Моя основная проблема - это вторая строка. «Новый» статус означает, что объект с id 5 был просто добавлен в базу данных. Он всегда должен быть первым статусом для любого идентификатора в таблице. Однако есть много случаев, когда «новая» запись была вставлена ​​примерно через три секунды ПОСЛЕ первоначальной записи изменений. В этом случае он был добавлен с адресом 1.0.1, затем изменен на 1.0.2, затем на 2.0.1, затем 3.0.1. (Изменить: реальные примеры не являются простыми или понятными, но всегда есть «путь» местоположений, которые человек может легко распознать.)

У меня возникают проблемы с попыткой написать запрос, который учитывает как строку 1 и строка 3. Я не могу просто найти самую последнюю запись, потому что они могут быть не в порядке. Я не могу просто захватить запись с помощью new_loc, который соответствует моему статусу, потому что может быть несколько совпадений.

Вот что я думаю будет работать:

  1. Найти самую последнюю предыдущее изменение местоположения, если таковой существует, и использовать его new_loc.
  2. Если никаких предыдущих изменений не существует, найдите запись с «новым» статусом для этого идентификатора и используйте ее new_loc.

В настоящее время у меня LEFT JOIN, который совпадает с BOTH этими условиями, но я не знаю, как сказать «присоединяться только к условию 2, если ничего не согласовано с условием 1» или «предпочитает строки, соединенные условием 1».

Я просто не могу понять, как это сделать. Любая помощь приветствуется.

Редактировать: Я должен четко указать, что идентификатор является идентификатором объекта, а не только индексом в этой таблице. Первичный ключ - это (id, status).

+0

Являются ли места монотонно увеличивающимися? Если это так, вы можете заказать по местоположению (или его фрагментам), чтобы определить, какое местоположение было ранее текущего. – encoded

+0

Нет, к сожалению, нет такой рифмы или причины, что строки местоположения произвольны, а изменения случайны. Я выбрал только эти примеры, потому что им легче следовать, сохраняя при этом структуру. – wizzard

ответ

0

Позвольте мне просто подтвердить, что я понимаю, что вы пытаетесь сделать. В псевдокоде это сделает то, что вы ищете?

given 
    table A (as in your answer) 
    table B (objectid, old, new) 
for any `id` 
    get all rows 
    order rows by `status` column such that 'new' is the first value, and then numerically 
    take the location in the first `status` column c and insert it into table B with values id, 'new', (c).location 
    for all remaining `status` fields selected: 
     for any field n, insert into table B with values id, (n-1).location, (n).location 

Это должно быть возможно с помощью хранимой процедуры ... но это может быть болезненный бит кода для записи.

Смежные вопросы