MySQL: I need to get the offset of a item in a query

别等时光非礼了梦想. 提交于 2019-12-06 15:47:51
Daniel Vassallo

If your images have sequential IDs, you may want to do the following:

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

Replace the ? parameter in the above query with the ID of the image requested.


UPDATE: It seems that your images are not ordered by a sequential ID, but by a timestamp. Unfortunately it looks like MySQL does not support variable expressions in the LIMIT clause (Source). One option would be to use a prepared statement:

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

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

EXECUTE stmt USING @lower_limit;

Another option could be:

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;
R. Martinho Fernandes

EDIT: It appears MySQL does not allow this kind of expression in the OFFSET clause. If you can use a prepared statement (either directly in SQL or in another language), you can make the calculation beforehand and use it. See Daniel's answer for that. I'm leaving this answer here because of the other useful information.

What you are looking for is called pagination. In MySQL you can do it with the LIMIT and OFFSET keywords:

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

Replace ? with the requested image index. Note that this will give images with offsets 60, 61, 62, 63, 64, 65 when you ask for image 62. I assumed the last offset you gave in the examples was exclusive. You should adjust accordingly if I made the wrong assumption.

And a little explanation:

LIMIT makes the query return only the given number of results. Because you always want six, that makes it easy.

OFFSET makes the query return only results from the given offset. The calculation does integer division by six and multiplies by six. This results in the previous multiple of six of the given number, exactly what you want.

I may not understand you, but why do you have to do everything in MySQL?

Let's assume you use LAMP:

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

Now you have start of your pagination in $pagination_start [i.e. 60] and requested image offset [i.e. 62] in $offset_mysql:

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

Now in return, you get an array cotaning 6 images and the one requested is at $result[$offset_array].

SELECT   image
FROM     images
ORDER BY updated_at
LIMIT    6, FLOOR($number / 6 ) * 6;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!