MySql - Как получить значение в предыдущей строке и значение в следующей строке?
У меня есть следующая таблица с именем Example
:
id(int 11) //not autoincriment
value (varchar 100)
Он имеет следующие строки данных:
0 100
2 150
3 200
6 250
7 300
Обратите внимание, что значения id не смежны.
Я написал этот SQL:
SELECT * FROM Example WHERE id = 3
Однако я не знаю, как получить значение предыдущего id
и значение следующего id
...
Пожалуйста, помогите мне получить предыдущее значение и следующее значение, если id
= 3?
P.S.: В моем примере это будет: previous - 150
, next - 250
.
Ответы
Ответ 1
Выберите следующую строку ниже:
SELECT * FROM Example WHERE id < 3 ORDER BY id DESC LIMIT 1
Выберите следующую строку выше:
SELECT * FROM Example WHERE id > 3 ORDER BY id LIMIT 1
Выберите оба варианта в одном запросе, например. используйте UNION:
(SELECT * FROM Example WHERE id < 3 ORDER BY id DESC LIMIT 1)
UNION
(SELECT * FROM Example WHERE id > 3 ORDER BY id LIMIT 1)
Что вы имеете в виду?
Ответ 2
Решение заключалось бы в использовании временных переменных:
select
@prev as previous,
e.id,
@prev := e.value as current
from
(
select
@prev := null
) as i,
example as e
order by
e.id
Чтобы получить "следующее" значение, повторите процедуру. Вот пример:
select
id, previous, current, next
from
(
select
@next as next,
@next := current as current,
previous,
id
from
(
select @next := null
) as init,
(
select
@prev as previous,
@prev := e.value as current,
e.id
from
(
select @prev := null
) as init,
example as e
order by e.id
) as a
order by
a.id desc
) as b
order by
id
Отметьте пример в SQL Fiddle
Может быть излишним, но это может помочь вам
Ответ 3
попробуйте sqlFiddle
SELECT value,
(SELECT value FROM example e2
WHERE e2.value < e1.value
ORDER BY value DESC LIMIT 1) as previous_value,
(SELECT value FROM example e3
WHERE e3.value > e1.value
ORDER BY value ASC LIMIT 1) as next_value
FROM example e1
WHERE id = 3
Изменить: OP упомянул, чтобы захватить значение предыдущего id
и значение следующего id
в одном из комментариев, поэтому код здесь SQLFiddle
SELECT value,
(SELECT value FROM example e2
WHERE e2.id < e1.id
ORDER BY id DESC LIMIT 1) as previous_value,
(SELECT value FROM example e3
WHERE e3.id > e1.id
ORDER BY id ASC LIMIT 1) as next_value
FROM example e1
WHERE id = 3
Ответ 4
SELECT *,
(SELECT value FROM example e1 WHERE e1.id < e.id ORDER BY id DESC LIMIT 1 OFFSET 0) as prev_value,
(SELECT value FROM example e2 WHERE e2.id > e.id ORDER BY id ASC LIMIT 1 OFFSET 0) as next_value
FROM example e
WHERE id=3;
И вы можете поместить свое собственное смещение после ключевого слова OFFSET
, если вы хотите выбрать записи с более высокими смещениями для следующих и предыдущих значений из выбранной записи.
Ответ 5
В этом запросе используется пользовательская переменная для вычисления расстояния от целевого идентификатора и серия запросов обертки для получения желаемых результатов. За один проход делается только один проход, поэтому он должен хорошо работать.
select * from (
select id, value from (
select *, (@x := ifnull(@x, 0) + if(id > 3, -1, 1)) row from (
select * from mytable order by id
) x
) y
order by row desc
limit 3
) z
order by id
См. SQLFiddle
Если вам не нужен окончательный порядок строк, вы можете опустить внешний запрос оболочки.
Ответ 6
Здесь мое решение может подойдет вам:
SELECT * FROM Example
WHERE id IN (
(SELECT MIN(id) FROM Example WHERE id > 3),(SELECT MAX(id) FROM Example WHERE id < 3)
)
Демо: http://sqlfiddle.com/#!9/36c1d/2
Ответ 7
Возможное решение, если вам нужно все в одной строке
SELECT t.id, t.value, prev_id, p.value prev_value, next_id, n.value next_value
FROM
(
SELECT t.id, t.value,
(
SELECT id
FROM table1
WHERE id < t.id
ORDER BY id DESC
LIMIT 1
) prev_id,
(
SELECT id
FROM table1
WHERE id > t.id
ORDER BY id
LIMIT 1
) next_id
FROM table1 t
WHERE t.id = 3
) t LEFT JOIN table1 p
ON t.prev_id = p.id LEFT JOIN table1 n
ON t.next_id = n.id
Пример вывода:
| ID | VALUE | PREV_ID | PREV_VALUE | NEXT_ID | NEXT_VALUE |
|----|-------|---------|------------|---------|------------|
| 3 | 200 | 2 | 150 | 4 | 250 |
Вот SQLFiddle демо
Ответ 8
Если у вас нет идентификатора, это сработало для меня.
Далее:
Выберите * из имени таблицы, где имя столбцa > текущий порядок данных столбца по имени столбца ASC limit 1
Предыдущая:
Выберите * из имени таблицы, где имя столбца < текущий порядок данных столбца по названию столбца DESC limit 1
Я использую это для списка членства, где поиск находится на фамилии члена. Пока у вас есть данные из текущей записи, он отлично работает.