我想构建一个在表中显示所有结果的查询,但从表的开头偏移 5。据我所知,MySQLLIMIT
需要一个限制和一个偏移量。有没有办法做到这一点?
10 回答
要检索从某个偏移量到结果集末尾的所有行,您可以为第二个参数使用一些较大的数字。此语句检索从第 96 行到最后一行的所有行:
SELECT * FROM tbl LIMIT 95, 18446744073709551615;
正如您提到的 LIMIT 是必需的,因此您需要使用可能的最大限制,即 18446744073709551615 (无符号 BIGINT 的最大值)
SELECT * FROM somewhere LIMIT 18446744073709551610 OFFSET 5
如其他答案中所述,MySQL 建议使用 18446744073709551615 作为限制中的记录数,但请考虑一下:如果您有 18,446,744,073,709,551,615 条记录,您会怎么做?事实上,如果你有 1,000,000,000 条记录,你会怎么做?
也许您确实想要超过 10 亿条记录,但我的意思是您想要的数量有一些限制,并且少于 18 quintillion。为了稳定性、优化和可能的可用性,我建议对查询设置一些有意义的限制。这也将减少任何从未见过这个神奇数字的人的困惑,并有额外的好处,即至少可以传达您愿意一次处理多少记录。
如果您真的必须从数据库中获取所有 18 个 quintillion 记录,那么您真正想要的可能是以 1 亿为增量获取它们并循环 1840 亿次。
另一种方法是选择一个自动增加的列,然后使用 HAVING 对其进行过滤。
SET @a := 0;
select @a:=@a + 1 AS counter, table.* FROM table
HAVING counter > 4
但我可能会坚持使用上限方法。
正如其他人提到的,来自 MySQL 手册。为了实现这一点,您可以使用无符号大整数的最大值,即这个可怕的数字 (18446744073709551615)。但是为了让它不那么混乱,你可以使用波浪号“~”位运算符。
LIMIT 95, ~0
它作为按位否定工作。“~0”的结果是 18446744073709551615。
您可以使用带有 LIMIT 的 MySQL 语句:
START TRANSACTION;
SET @my_offset = 5;
SET @rows = (SELECT COUNT(*) FROM my_table);
PREPARE statement FROM 'SELECT * FROM my_table LIMIT ? OFFSET ?';
EXECUTE statement USING @rows, @my_offset;
COMMIT;
在 MySQL 5.5.44 中测试。因此,我们可以避免插入数字 18446744073709551615。
注意:事务确保变量@rows 与执行语句时考虑的表一致。
我在练习LC#1321时遇到了一个非常相似的问题,我必须选择所有日期,但前 6 个日期被跳过。
我借助ROW_NUMBER()
窗口函数和子查询在 MySQL 中实现了这一点。例如,以下查询返回跳过前五行的所有结果:
SELECT
fieldname1,
fieldname2
FROM(
SELECT
*,
ROW_NUMBER() OVER() row_num
FROM
mytable
) tmp
WHERE
row_num > 5;
您可能需要在子查询中添加更多逻辑,尤其是OVER()
为了满足您的需要。此外,可以使用RANK()
/窗口函数而不是取决于您的实际偏移逻辑。DENSE_RANK()
ROW_NUMBER()
参考:
我知道这很旧,但我没有看到类似的响应,所以这是我将使用的解决方案。
首先,我将对表执行计数查询以查看存在多少条记录。此查询速度很快,通常执行时间可以忽略不计。就像是:
SELECT COUNT(*) FROM table_name;
然后,我将使用从 count 获得的结果作为我的限制来构建我的查询(因为这是表可能返回的最大行数)。就像是:
SELECT * FROM table_name LIMIT count_result OFFSET desired_offset;
或者可能是这样的:
SELECT * FROM table_name LIMIT desired_offset, count_result;
当然,如有必要,您可以从 count_result 中减去 desired_offset 以获得一个实际的、准确的值作为限制。如果我实际上可以确定要提供的适当限制,则传递“18446744073709551610”值是没有意义的。
就在今天,我正在阅读有关从 mysql 表中获取大量数据(超过一百万行)的最佳方法。一种方法是,如建议的那样,使用LIMIT x,y
wherex
是偏移量和y
要返回的最后一行。但是,正如我发现的那样,这并不是最有效的方法。如果您有一个自动增量列,您可以轻松地使用SELECT
带有WHERE
子句的语句,说明您想从哪条记录开始。
例如,
SELECT * FROM table_name WHERE id > x;
似乎 mysql 在您使用时会获得所有结果LIMIT
,然后只向您显示适合偏移量的记录:不是最好的性能。
资料来源:回答这个问题MySQL 论坛。请注意,这个问题大约有 6 年的历史。
WHERE .... AND id > <YOUROFFSET>
id 可以是您拥有的任何自动递增或唯一的数字列...