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

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