在单个 SQL 查询中获取两个下一个和两个上一个条目

Posted

技术标签:

【中文标题】在单个 SQL 查询中获取两个下一个和两个上一个条目【英文标题】:Fetch two next and two previous entries in a single SQL query 【发布时间】:2009-01-02 12:09:51 【问题描述】:

我想显示一个图片库,并且在视图页面上,应该可以看到一堆缩略图:当前图片,包含前面的两个条目和后面的两个条目。

获取两个下一个/上一个的问题是我不能(除非我弄错了)选择像 MAX(id) WHERE idxx 这样的东西。

有什么想法吗?

注意:当然 id 不跟随,因为它们应该是多个 WHERE 实例的结果。

谢谢 马歇尔

【问题讨论】:

【参考方案1】:

请原谅 SQL Server 风格的变量名,我不记得 mysql 是如何进行变量命名的。

SELECT *
  FROM photos
 WHERE photo_id = @current_photo_id
 UNION ALL
SELECT *
  FROM photos
 WHERE photo_id > @current_photo_id
 ORDER BY photo_id ASC
 LIMIT 2
 UNION ALL
SELECT *
  FROM photos
 WHERE photo_id < @current_photo_id
 ORDER BY photo_id DESC
 LIMIT 2;

此查询假定您可能有不连续的 ID。但是,从长远来看,如果您的表中有很多照片,因为经常在从数据库中检索到整个结果集之后评估 TOP,这可能会成为问题。 YMMV。

在高负载情况下,我可能会使用这些查询,但我也会定期预实现它们,以便每张照片都有一个 PreviousPhotoOne、PreviousPhotoTwo 等列。维护起来有点多,但是当你有大量静态数据并且需要性能时,它工作得很好。

【讨论】:

【参考方案2】:

如果你的 ID 是连续的,你可以这样做

where id >= @id-2 and id <= @id+2

否则我认为你必须union 3 次查询,一个以获取具有给定 id 的记录,另外两个与 toporder by 这样搞乱

select *
from table
where id = @id

union

select top 2 *
from table
where id < @id
order by id desc

union

select top 2 *
from table
where id > @id
order by id

性能不会太差,因为您没有检索大量数据集,但由于使用union,性能不会很好。

如果您发现性能开始出现问题,您可以添加列来保存上一个和下一个项目的 ID;使用触发器或通宵过程或其他方式计算 id。这意味着您只需执行一次硬查询,而不是每次需要时执行。

【讨论】:

注意:“TOP 2”是专有的 Microsoft/Sybase 语法,MySQL 不支持。相反,MySQL 使用出现在 ORDER BY 子句之后的可选 LIMIT 子句。【参考方案3】:

我认为这种方法应该适用于非连续 ID,并且应该比使用 UNION 更有效。 currentID 将使用 SQL 中的常量或从您的程序传递来设置。

SELECT * FROM photos WHERE ID = currentID OR ID IN (
    SELECT ID FROM photos WHERE ID < currentID ORDER BY ID DESC LIMIT 2
) OR ID IN (
    SELECT ID FROM photos WHERE ID > currentID ORDER BY ID ASC LIMIT 2
) ORDER BY ID ASC

【讨论】:

您不应该在 WHERE 子句中使用 OR 而不是 AND 吗?【参考方案4】:

如果您只是对 id 的上一条和下一条记录感兴趣,您不能只使用一个 where 子句来限制 WHERE id=xx, xx-1, xx-1, xx+1, xx+2 使用多个 WHERE子句或使用 WHERE IN ?

【讨论】:

这将适用于您有一个连续的标识列的理想世界,但有时您最终会出现间隙(插入失败、删除等)。我发现最好使用 TOP x 结合 WHERE 来获得最接近的。

以上是关于在单个 SQL 查询中获取两个下一个和两个上一个条目的主要内容,如果未能解决你的问题,请参考以下文章

SQLAlchemy 单个查询从两个表中返回列

如何使用单个 SQL 聚合函数查询为同一个聚合函数获取多个结果?

sql一个表中同时查询两个count的sql语句

如何在同一个表上组合两个查询以在 MySQL 中获得单个结果集

sql语言如何查询一条记录中含有两个关键字?

如何根据单个表中的两个列值获取 1 条记录?