У меня есть таблица, такая как (упрощенная до крайности, чтобы сделать ее более понятной)
create table mytable (
id integer not null,
owner text not null,
order_field_1 integer not null,
order_field_2 integer not null
)
Я пытаюсь получать идентификаторы следующего и предыдущего элементов каждый раз, когда получаю строку из базы данных, чтобы разрешить навигацию. Строки упорядочены не по id, а по ORDER BY order_field_1 DESC, order_field_2 DESC
.
При получении последних записей для владельца, у меня нет проблем, чтобы найти то, что я хочу, используя окно и привести / отставание
SELECT
id,
owner,
lag(id) over w AS previous_id,
lead(id) over w AS next_id
FROM
mytable
WHERE
owner = 'someuser'
WINDOW w AS (
ORDER BY order_field_1 DESC,
order_field_2 DESC
)
ORDER BY
order_field_1 DESC,
order_field_2 DESC
LIMIT
5
Это написано по памяти, но это суть, и она отлично работает.
Моя проблема в том, что когда я хочу получить определенную строку, используя владельца и идентификатор, но я все еще хочу найти предыдущий и следующий идентификаторы, я больше не могу использовать оконную функцию, так как где возвращается только одна строка, и мое текущее решение сделать подзапрос для получения обоих идентификаторов навигации не очень хорошая производительность
Например, (я поставил только предыдущий идентификатор, так как он следующий для следующего)
SELECT
m1.id,
m1.owner,
(
SELECT
m2.id
FROM
mytable m2
WHERE
m2.owner = m1.owner
AND m2.id != m1.id
AND (
m2.order_field_1 < m1.order_field_1
OR (
m2.order_field_1 = m1.order_field_1
AND m2.order_field_2 <= m1.order_field_2
)
ORDER BY
m2.order_field_1 DESC,
m2.order_field_2 DESC
LIMIT
1
) AS previous_id
FROM
mytable m1
WHERE
owner = 'someuser'
AND id = 12345
Итак, я выбираю свою строку, затем выбираю первую строку от того же пользователя с другим идентификатором, то есть либо с более низким полем порядка_1, либо с тем же, но с более низким полем порядка_2.
Это не очень эффективно, и я получаю плохие результаты, и мне интересно, есть ли у кого-нибудь идеи о том, как я мог бы это улучшить?
Пример набора данных:
id | owner | order_field_1 | order_field_2
1 | someuser | 4 | 2
2 | someuser | 2 | 8
3 | someuser | 4 | 3
4 | someuser | 3 | 2
5 | someuser | 4 | 6
6 | someuser | 4 | 5
Заказанный:
id | owner | order_field_1 | order_field_2
5 | someuser | 4 | 6
6 | someuser | 4 | 5
3 | someuser | 4 | 3
1 | someuser | 4 | 2
4 | someuser | 3 | 2
2 | someuser | 2 | 8
Если я выберу владельца = 'someuser' и id = 3, предыдущий_ид должен быть 1, следующий_ид должен быть 6.
Если я выберу владельца = 'someuser' и id = 1, предыдущий_ид должен быть 4, следующий_ид должен быть 3.
Заранее спасибо за любую помощь