MySql - 如何获取上一行中的值和下一行中的值?

时间:2013-12-30 23:07:14

标签: mysql sql

我有下表,名为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。:在我的示例中,它将是:上一个 - 150,下一个 - 250

8 个答案:

答案 0 :(得分:18)

选择下面的下一行:

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)

那是什么意思?

答案 1 :(得分:11)

解决方案是使用临时变量:

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

检查the example on SQL Fiddle

可能有点矫枉过正,但它可能有所帮助

答案 2 :(得分:7)

请尝试 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

答案 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关键字后放置自己的偏移量。

答案 4 :(得分:2)

我的解决方案可能适合您:

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

答案 5 :(得分:1)

此查询使用用户定义的变量来计算与目标ID的距离,以及一系列包装器查询以获得所需的结果。只有一次通过表,所以它应该表现良好。

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 :(得分:0)

如果您需要一行中的所有可能的解决方案

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 演示

答案 7 :(得分:0)

如果您没有身份证,这对我有用。

下一步:

SELECT * FROM table_name
WHERE column_name > current_column_data
ORDER BY column_name ASC
LIMIT 1

一个:

SELECT * FROM table_name
WHERE column_name < current_column_data
ORDER BY column_name DESC
LIMIT 1

我将此用作成员列表,其中搜索位于成员的姓氏上。只要您拥有当前记录中的数据,它就可以正常工作。