【问题标题】:MySQL: I need to get the offset of a item in a queryMySQL:我需要在查询中获取项目的偏移量
【发布时间】:2011-02-03 17:29:30
【问题描述】:

Mysql:我需要获取查询中某项的偏移量。

我有一个图像库:每个堆栈显示 6 个图像,所以当我请求图像 22 时,它会显示从 18 到 24 的图像。它应该首先获取图像 22 的偏移量,然后获取从 18 到 24 的图像。

另一个例子:我请求图像编号 62(和偏移量 62),它将选择偏移量从 60 到 66 的图像。

单个查询可以吗?

主要是获取id等于数字的item的偏移值。

谢谢 ;)

编辑: select * from images order_by updated_at offset(这里我需要在此查询中获取图像 id 的偏移量,并进行一些计算......这就是我需要的,如果可能的话......:d)

EDIT2: 现在我知道我需要 2 个查询:

1º:使用我的自定义顺序获取查询中图像的偏移量

2º:使用第一个查询的偏移量获取图像...这个我可以单独完成,第一个是问题..:s

【问题讨论】:

  • 你要的叫分页。

标签: mysql sorting select offset


【解决方案1】:

如果您的图像具有连续的 ID,您可能需要执行以下操作:

SELECT    * 
FROM      images 
WHERE     id >= ((? DIV 6) * 6) AND 
          id < (((? DIV 6) + 1) * 6)
ORDER BY  id;

将上述查询中的?参数替换为所请求图片的ID。


更新:您的图像似乎不是按顺序 ID 排序的,而是按时间戳排序的。不幸的是,MySQL 似乎不支持 LIMIT 子句 (Source) 中的变量表达式。一种选择是使用准备好的语句:

PREPARE stmt FROM 
" SELECT    * 
  FROM      images
  ORDER BY  updated_at
  LIMIT     ?, 6";

SET @lower_limit := ((22 DIV 6) * 6);

EXECUTE stmt USING @lower_limit;

另一个选项可能是:

SET @row = 0;

SELECT    * 
FROM      images 
WHERE     (@row := @row + 1) BETWEEN ((3 DIV 6) * 6) + 1 and (((3 DIV 6) + 1) * 6)
ORDER BY  updated_at;

【讨论】:

  • 但不按id排序,按时间戳排序,updated_at
  • 使用余数运算符的表达式没有给出正确的结果。 ((62 % 6) - 1) * 6 = 6。你想要的是整数除法的商。剩下的你永远不会得到超过 24 的任何结果,对于小于 6 的输入,你可以得到 -6。
  • 您只使用 id,但我真正需要的是带有 order_by = "updated_at" 的查询中图像的偏移量。因此,如果我请求图像 id=22,按“updated_at”排序将获得 4 的偏移量,例如,不是 22。
  • @user305270:你没有在你的问题中说清楚,因为在你所有的例子中,id 和 offset 都是一样的。
  • @Daniel: 仍然不对... (22 DIV 6 - 1) * 6 - 1 = 11... 就像 (22 DIV 6) * 6 一样简单。
【解决方案2】:

编辑: 看来 MySQL 不允许在 OFFSET 子句中使用这种表达式。如果您可以使用准备好的语句(直接用 SQL 或其他语言),您可以预先进行计算并使用它。请参阅Daniel 的答案。由于其他有用的信息,我将把这个答案留在这里。

您要查找的内容称为分页。在 MySQL 中,您可以使用 LIMITOFFSET 关键字:

SELECT   image
FROM     images
ORDER BY updated_at
LIMIT    6
OFFSET   (DIV(?, 6) * 6)

? 替换为请求的图像索引。请注意,当您要求图像 62 时,这将给出偏移量为 60、61、62、63、64、65 的图像。我假设您在示例中给出的最后一个偏移量是独占的。如果我做出了错误的假设,你应该相应地调整。

还有一点解释:

LIMIT 使查询只返回给定数量的结果。因为你总是想要六个,这很容易。

OFFSET 使查询仅返回给定偏移量的结果。该计算将整数除以六并乘以六。这将得到给定数字的前六的倍数,​​这正是您想要的。

【讨论】:

  • MySQL(至少版本 5.0.51a)不支持 OFFSET 子句中的那种表达式...我不确定以后的版本。
  • @Daniel:这很糟糕。我猜张贴者需要使用带有变量的解决方案。
  • 是的,很遗憾 LIMITOFFSET 参数必须是整数常量...此处列出了错误/功能请求:bugs.mysql.com/bug.php?id=11918。 5.1 版似乎没有修复它。
  • 它也不起作用。但是我如何得到“?”?这 ?不是图像的 id,是该图像在查询中的偏移量。
【解决方案3】:

我可能不明白你,但为什么你必须在 MySQL 中做所有事情?

假设您使用 LAMP:

$pagination_start = (int)(floor($id_requested / 6)*6);
$offset_array = ($id_requested % 6);
$offset_mysql = $pagination_start + $offset_array;

现在你的分页在$pagination_start [i.e. 60]和请求的图像偏移量[即62] 在$offset_mysql:

SELECT   image
FROM     images
ORDER BY updated_at DESC
LIMIT    $pagination_start, 6

现在作为回报,您会得到一个包含 6 张图像的数组,请求的图像位于 $result[$offset_array]

【讨论】:

  • OP 之前没有明确说明,但是当请求的是 id 为 22 的图像时,该图像可以说是第 62 个最近更新的图像。那么我们想要的是让查询返回第 60 到第 66(我假设是唯一的上限)最近更新的查询。至少这是我从他的 cmets 那里得到的。
  • 啊。现在我删除了我的和?回答并再次考虑:D
  • 我仍然认为他实际上并没有请求id,但更像是number at position XY in this gallery——在这种情况下,这就像承诺的那样工作:)
  • 你不处理查询中的偏移位置,而只是处理一行的 id。
【解决方案4】:
SELECT   image
FROM     images
ORDER BY updated_at
LIMIT    6, FLOOR($number / 6 ) * 6;

【讨论】:

猜你喜欢
  • 2021-07-09
  • 1970-01-01
  • 1970-01-01
  • 2015-10-18
  • 2019-04-07
  • 1970-01-01
  • 2014-07-26
  • 2012-05-30
  • 1970-01-01
相关资源
最近更新 更多