【问题标题】:Next and previous records in mysql after sorting desc排序后mysql中的下一条和上一条记录
【发布时间】:2013-03-26 09:43:52
【问题描述】:

我有一个名为 users 的简单表,其中包含以下数据:

id | hops
 1 | 3
 2 | 1
 3 | 5
 4 | 2
 5 | 6
 6 | 5

我想根据跳数降序进行上一个/下一个导航。我使用以下查询进行降序排序:

SELECT * FROM users ORDER BY hops DESC, id DESC

这是结果:

id | hops
 5 | 6
 6 | 5
 3 | 5
 1 | 3
 4 | 2
 2 | 1

现在我想要的是,当我在 mysql 查询中输入任何 id 时,我会根据上面的排序获得上一个和下一个 id。例如:

对于 id 5(在这种情况下,id=5 的跳数最高,因此之前没有任何记录):

id (current) | hops (current) | id (prev) | hops (prev) | id (next) | hops (next)
   5         |    6           |  NULL     | NULL        |  6        |  5

对于 id 6:

id (current) | hops (current) | id (prev) | hops (prev) | id (next) | hops (next)
   6         |    5           |  5        |     6       |  3        |  5

对于 id 3:

id (current) | hops (current) | id (prev) | hops (prev) | id (next) | hops (next)
   3         |    5           |  6        |    5        |  1        |  3

对于 id 1:

id (current) | hops (current) | id (prev) | hops (prev) | id (next) | hops (next)
   1         |    3           |  3        |    5        |  4        |  2

对于 id 4:

id (current) | hops (current) | id (prev) | hops (prev) | id (next) | hops (next)
   4         |    2           |  1        | 3           |  2        |  1

对于 id 2(在这种情况下,id=2 的跳数最少,因此在它之后没有下一条记录)

id (current) | hops (current) | id (prev) | hops (prev) | id (next) | hops (next)
   2         |    1           |  4        | 2           |  NULL     |  NULL

谢谢

【问题讨论】:

  • 你的表中的 7 在哪里?
  • 对不起...这是一个错误:)

标签: php mysql sql database sorting


【解决方案1】:

试试:

select cp.*, n.id id_next, n.hops hops_next
from
(select c.id id_current, c.hops hops_current, p.id id_previous, p.hops hops_previous
 from
 (select * from users where id = ?) c
 left join users p on c.hops < p.hops or (c.id < p.id and c.hops = p.hops)
 order by p.hops, p.id limit 1) cp 
left join users n 
       on cp.hops_current > n.hops or (cp.id_current > n.id and cp.hops_current = n.hops)
order by n.hops desc, n.id desc limit 1

(SQLFiddle here)

【讨论】:

    【解决方案2】:

    这是迄今为止我见过的最奇怪的用户表。无论如何,这是一种方法(虽然我不得不承认它有点复杂)......

    DROP TABLE IF EXISTS test;
    
    CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,hops INT NOT NULL);
    
    INSERT INTO test VALUES
    (1 ,3),(2 ,1),(3,5),(4 ,2),(5 ,6),(6 ,5);
    
    SELECT c.id id_curr
         , c.hops hops_curr
         , p.id id_prev
         , p.hops hops_prev
         , n.id id_next
         , n.hops hops_next
      FROM
         (
           SELECT a.*
                , COUNT(*) new_rank
             FROM 
                ( SELECT x.*
                       , COUNT(*) rank 
                    FROM test x 
                    JOIN test y 
                      ON y.hops >= x.hops 
                   GROUP 
                      BY x.id
                ) a
             JOIN 
                ( SELECT x.*
                       , COUNT(*) rank 
                    FROM test x 
                    JOIN test y 
                      ON y.hops >= x.hops 
                   GROUP 
                      BY x.id
                ) b
               ON b.rank < a.rank
               OR (b.rank = a.rank AND b.id >= a.id)
            GROUP 
               BY a.id
         )c
      LEFT
      JOIN
         (
           SELECT a.*
                , COUNT(*) new_rank
             FROM 
                ( SELECT x.*
                       , COUNT(*) rank 
                    FROM test x 
                    JOIN test y 
                      ON y.hops >= x.hops 
                   GROUP 
                      BY x.id
                ) a
             JOIN 
                ( SELECT x.*
                       , COUNT(*) rank 
                    FROM test x 
                    JOIN test y 
                      ON y.hops >= x.hops 
                   GROUP 
                      BY x.id
                ) b
               ON b.rank < a.rank
               OR (b.rank = a.rank AND b.id >= a.id)
            GROUP 
               BY a.id
         ) p
        ON p.new_rank = c.new_rank-1
      LEFT
      JOIN
         (
           SELECT a.*
                , COUNT(*) new_rank
             FROM 
                ( SELECT x.*
                       , COUNT(*) rank 
                    FROM test x 
                    JOIN test y 
                      ON y.hops >= x.hops 
                   GROUP 
                      BY x.id
                ) a
             JOIN 
                ( SELECT x.*
                       , COUNT(*) rank 
                    FROM test x 
                    JOIN test y 
                      ON y.hops >= x.hops 
                   GROUP 
                      BY x.id
                ) b
               ON b.rank < a.rank
               OR (b.rank = a.rank AND b.id >= a.id)
            GROUP 
               BY a.id
         ) n
        ON n.new_rank = c.new_rank+1
     ORDER 
        BY c.hops DESC
         , c.id DESC;
    

    【讨论】:

    • 插入新列 ID 自动增量的最佳方法
    • 感谢您的努力,但其他解决方案对我来说似乎更直接,因此必须选择它:)
    • 我原以为此查询返回所有结果而不是仅返回一个结果这一事实将是一个关键 - 但是,嘿,我知道什么 ;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多