Задать вопрос
@shupike

Как в выборке sql обратиться к предыдущей записи?

Всем доброго дня! Подскажите, пожалуйста, по php - формирую запрос к базе, пробегаю по выборке (если упростить задачу - по серийному номеру оборудования ищу записи в таблицах и вытаскиваю последнюю дату - то есть как бы из истории перемещений этого оборудования нахожу его последнее местонахождение). Но мне нужно не только последнюю дату и местоположение получить, а и предыдущего владельца. Скажем, выглядят итоги запроса вот так:
Устройство | Серийный | Дата получения | Местоположение
Ноутбук | 12349647 | 21.03.25 | Склад
Ноутбук | 12349647 | 15.01.25 | Сотрудник_1
Ноутбук | 12349647 | 30.08.24 | Склад
Ноутбук | 12349647 | 22.05.24 | Сотрудник_2

Я просто вставляю order by date (поле даты) и забираю последнюю строчку. Но нужно еще и зацепить предыдущего владельца, в данном примере - Сотрудника_1. Вот не пойму, как это сделать... Я посчитал число перемещений по каждой единице оборудования:
$count=0;
while ($row2 = pg_fetch_row($result2)) {
$last_date = $row2[2];
$last_owner = $row2[1];
$count=$count+1;
}
Но как внутри while обратиться не к текущей строке, а еще и к предыдущей в выборке? Заранее огромное спасибо за советы.
  • Вопрос задан
  • 84 просмотра
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 5
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
ORDER BY date DESC 
LIMIT 2

Получите последнюю и предпоследнюю записи.
Ответ написан
Комментировать
@d-stream
Готовые решения - не подаю, но...
Изучаем LAG и LEAD потом выясняем - есть ли они для своего, а не абстрактного sql
И если есть - наслаждаемся.
Ответ написан
@Akina
Сетевой и системный админ, SQL-программист.
Я просто вставляю order by date (поле даты) и забираю последнюю строчку.

Глупо.

Используй ORDER BY date DESC - и тогда можно, во-первых, брать первую строку, а не мотать вниз до последней, во-вторых, нужная "предыдущая" строка при обратной сортировке будет "следующая" - ну то есть вторая.

PS. Дата - ненадёжный критерий сортировки. За один день комп могут сдать на склад и выдать другому товарищу - и будешь ты гадать, какая из двух записей актуальная, а какая для неё предыдущая. Я уж не говорю о вводах и корректировках "задним числом".
Ответ написан
Комментировать
ipatiev
@ipatiev Куратор тега PHP
Потомок старинного рода Ипатьевых-Колотитьевых
Чтобы внутри while обратиться к предыдущей записи, надо в самом низу цикла записывать текущую строку в переменную.
Тогда при следующей итерации цикла в ней будет предыдущая запись.
С любовью, Капитан Очевидность.
Ответ написан
Комментировать
@alexalexes
Устройство | Серийный | Дата получения | Местоположение
Ноутбук | 12349647 | 21.03.25 | Склад
Ноутбук | 12349647 | 15.01.25 | Сотрудник_1
Ноутбук | 12349647 | 30.08.24 | Склад
Ноутбук | 12349647 | 22.05.24 | Сотрудник_2

Такой способ записи с опорой на дату для построения исторической цепочки архитектурно не устройчив.
Чтобы историческая цепочка стала устойчивой, нужно вводить указатель на следующую или предыдущую запись.
ID | Устройство | Серийный | Дата получения | Местоположение | Следующий ID
11 | Ноутбук | 12349647 | 21.03.25 | Склад | null
8 | Ноутбук | 12349647 | 15.01.25 | Сотрудник_1 | 11
5 | Ноутбук | 12349647 | 30.08.24 | Склад | 8
1 | Ноутбук | 12349647 | 22.05.24 | Сотрудник_2 | 5

При всех CRUD операциях работы с историческим списком нужно корректно записывать next_id в предыдущей записи.
Можно произвольно перезаписывать все не служебные поля (кроме id и next_id), вплоть до серийника, и это не разрушит историческую цепочку.
Последняя запись в исторической цепочке всегда будет next_id is null.
Чтобы действительно корректно получать историческую цепочку, нужен рекурсивный запрос, но в простейших случаях достаточно сортировать цепочку по next_id.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы