当前位置: 首页 > 知识库问答 >
问题:

后端 - MySQL查询当前数据的上一条,下一条?

卢志业
2024-07-15

获取当前数据的上一条,下一条的 MySQL 代码:

WITH RankedRecords AS (    
    SELECT *,    
           LEAD(id) OVER (ORDER BY time ASC) AS next_id,    
           LAG(id) OVER (ORDER BY time ASC) AS prev_id    
    FROM records    
)    
SELECT r.id, r.time,  -- 其他字段
       CASE   
           WHEN r.id = @CurrentID THEN 'Current'  -- @CurrentID 是当前id
           WHEN r.prev_id = @CurrentID THEN 'Previous'  
           WHEN r.next_id = @CurrentID THEN 'Next'  
       END AS record_type  
FROM RankedRecords r  
WHERE r.id = @CurrentID OR r.prev_id = @CurrentID OR r.next_id = @CurrentID  
ORDER BY CASE WHEN record_type = 'Previous' THEN 1 ELSE 2 END, r.time ASC;

代码是一言生成的,测试达到了效果,想问问数据库大佬,这段代码如果对大量数据的查询会影响性能吗,像这一行:

   SELECT *, 
           LEAD(id) OVER (ORDER BY time ASC) AS next_id,    
           LAG(id) OVER (ORDER BY time ASC) AS prev_id    
   FROM records

数据库结构:

id time ···一些其他列
2 12345660 ···
3 12345640 ···
5 12345670 ···

查询id=2,以time排序:

id time ···一些其他列 record_type
3 12345640 ··· Previuous
5 12345670 ··· Next
2 12345660 ··· Current

查询id=3:

id time ···一些其他列 record_type
2 12345660 ··· Next
3 12345640 ··· Current

共有2个答案

金宣
2024-07-15
WITH RankedRecords AS (    
    SELECT id, time,  -- 只选择需要的列
           LEAD(id) OVER (ORDER BY time ASC) AS next_id,    
           LAG(id) OVER (ORDER BY time ASC) AS prev_id    
    FROM records    
)    
SELECT r.id, r.time,  -- 其他字段
       CASE   
           WHEN r.id = @CurrentID THEN 'Current'  -- @CurrentID 是当前id
           WHEN r.prev_id = @CurrentID THEN 'Previous'  
           WHEN r.next_id = @CurrentID THEN 'Next'  
       END AS record_type  
FROM RankedRecords r  
WHERE r.id = @CurrentID OR r.prev_id = @CurrentID OR r.next_id = @CurrentID  
ORDER BY CASE WHEN record_type = 'Previous' THEN 1 ELSE 2 END, r.time ASC;
江正德
2024-07-15

回答

该段代码使用了 MySQL 的窗口函数(LEADLAG)以及公用表表达式(CTE,即 WITH 子句),来查询当前数据行的前一条和后一条记录。这种查询方式在中等大小的数据集上通常是高效的,但在处理大量数据时,性能可能会受到影响,特别是如果 records 表非常大,或者没有适当的索引来支持 ORDER BY time ASC 排序。

对于性能优化,你可以考虑以下几点:

  1. 索引:确保 time 列有索引,这样 ORDER BY 操作可以更快地进行。
  2. 限制返回的数据量:如果你只对当前行、前一行和后一行感兴趣,那么可以在 WHERE 子句中添加额外的条件来限制返回的数据量,但这已经在你提供的查询中做到了。
  3. 查询计划:使用 EXPLAIN 关键字来查看查询的执行计划,检查是否使用了索引以及是否有任何潜在的性能瓶颈。
  4. 硬件和配置:确保数据库服务器有足够的 RAM 来缓存常用数据和索引,以及适当的 CPU 和磁盘 I/O 性能。
  5. 分区:如果 records 表非常大,并且数据可以按某种方式分区(例如按日期),那么可以考虑使用 MySQL 的分区功能来提高性能。
  6. 其他考虑:如果你经常需要执行此类查询,并且发现性能成为问题,那么可能需要考虑在数据插入或更新时预先计算并存储前一条和后一条记录的 ID,或者使用其他数据结构(如缓存)来存储这些信息。

关于你提到的这一行:

SELECT *, 
       LEAD(id) OVER (ORDER BY time ASC) AS next_id,    
       LAG(id) OVER (ORDER BY time ASC) AS prev_id    
FROM records

这一行本身并不会对性能产生特别大的影响,只要 time 列有索引并且表的大小不是极端的大。然而,它确实需要对整个 records 表进行排序操作,这是查询中最耗时的部分之一。

总的来说,对于中等大小的数据集,这个查询应该是足够高效的。但对于大数据集,你可能需要采取一些额外的措施来优化性能。

 类似资料:
  • 本文向大家介绍MySQL查询重复数据(删除重复数据保留id最小的一条为唯一数据),包括了MySQL查询重复数据(删除重复数据保留id最小的一条为唯一数据)的使用技巧和注意事项,需要的朋友参考一下 开发背景: 最近在做一个批量数据导入到MySQL数据库的功能,从批量导入就可以知道,这样的数据在插入数据库之前是不会进行重复判断的,因此只有在全部数据导入进去以后在执行一条语句进行删除,保证数据唯一性。

  • 我使用的是+++。 我得到了4个DELETE,只想要一个数据库请求,所以我用一个“;”连接了DELETE命令...但总是失败。 它会抛出以下错误: 但如果我将此SQL粘贴到PhpMyAdmin中,它总是成功的... 如果我在单个查询中编写它,它也会成功。 多谢帮忙!

  • 问题内容: 我正在使用+ + + 。 我有4个DELETE,并且只需要1个数据库请求,因此我将DELETE命令与“;” …相连,但是它总是失败。 它引发此错误: 但是,如果我将此SQL粘贴到PhpMyAdmin中,它将始终成功… 如果我在单个查询中写它也是成功的。 感谢帮助! 问题答案: 我猜您正在使用node-mysql。( 但也应该适用于 node- mysql2 ) 该文件说: 出于安全原因

  • 本文向大家介绍Mysql时间轴数据 获取同一天数据的前三条,包括了Mysql时间轴数据 获取同一天数据的前三条的使用技巧和注意事项,需要的朋友参考一下 创建表数据   添加数据省略   时间轴前2条数据 ps:下面看下MySQL 生成 时间轴 调用: 结果: 表结构: 总结 以上所述是小编给大家介绍的Mysql时间轴数据 获取同一天数据的前三条,希望对大家有所帮助,如果大家有任何疑问请给我留言,小

  • 本文向大家介绍一千万条数据的表, 如何分页查询?相关面试题,主要包含被问及一千万条数据的表, 如何分页查询?时的应答技巧和注意事项,需要的朋友参考一下 数据量过大的情况下, limit offset分页会由于扫描数据太多而越往后查询越慢. 可以配合当前页最后一条ID进行查询, SELECT * FROM T WHERE id > #{ID} LIMIT #{LIMIT}. 当然, 这种情况下ID必

  • 主要内容:单一条件的查询语句,多条件的查询语句在 MySQL 中,如果需要有条件的从数据表中查询数据,可以使用 WHERE 关键字来指定查询条件。 使用 WHERE 关键字的语法格式如下: WHERE 查询条件 查询条件可以是: 带比较运算符和逻辑运算符的查询条件 带 BETWEEN AND 关键字的查询条件 带 IS NULL 关键字的查询条件 带 IN 关键字的查询条件 带 LIKE 关键字的查询条件 单一条件的查询语句 单一条件指的是在

  • 问题内容: 嗨,我有一个带有日期字段和一些其他信息的表。我想选择过去一周(从星期日开始的一周)中的所有条目。 表值: 我想选择上周的所有ID,预期输出为5、6、8 (ID 2不在上周,ID 15在本周。) 怎么写和SQL Query相同。 问题答案:

  • 问题内容: 我将不胜感激创建此查询的任何帮助。我尝试了好几种方法,但都没有碰到运气。由于我的问题很难表达,因此我将举一个我想做的简单例子。我的数据在结构上类似于以下内容: 如果我有两种特定颜色的ID,我想创建一个查询以返回类型。例如,我想查找所有具有蓝色和红色的ID。然后查询将返回: A和B的返回顺序并不重要。数据集很大,我希望有许多ID可以同时满足这两个条件(也许是50,000个左右)。我要指出