MySQL偏移无限行

时间:2008-11-01 04:08:58

标签: mysql sql sql-limit

我想构建一个显示表中所有结果的查询,但是从表的开头偏移5。据我所知,MySQL的LIMIT需要限制和偏移量。有没有办法做到这一点?

10 个答案:

答案 0 :(得分:138)

来自MySQL Manual on LIMIT

  

从特定行检索所有行   偏移到结果的末尾   设置,你可以使用一些大数字   第二个参数。这个说法   从第96行检索所有行   到最后:

SELECT * FROM tbl LIMIT 95, 18446744073709551615;

答案 1 :(得分:22)

正如您所提到的,LIMIT是必需的,因此您需要使用可能的最大限制,即18446744073709551615(最大未签名BIGINT)

SELECT * FROM somewhere LIMIT 18446744073709551610 OFFSET 5

答案 2 :(得分:6)

正如其他答案所述,MySQL建议使用18446744073709551615作为限制中的记录数,但请考虑一下:如果您获得18,446,744,073,709,551,615条记录,您会怎么做?事实上,如果你有1,000,000,000条记录,你会怎么做?

也许你确实想要超过十亿条记录,但我的观点是你想要的数字有一些限制,并且它不到18个。为了稳定性,优化和可能的可用性,我建议对查询设置一些有意义的限制。这也可以减少任何从未见过这个神奇数字的人的混淆,并且还可以至少传达你愿意同时处理多少条记录的额外好处。

如果你真的必须从你的数据库中获取所有18个quintillion记录,也许你真正想要的是以1亿的增量获取它们并循环1840亿次。

答案 3 :(得分:5)

另一种方法是选择自动增量列,然后使用HAVING过滤它。

SET @a := 0; 
select @a:=@a + 1 AS counter, table.* FROM table 
HAVING counter > 4

但我可能会坚持使用上限方法。

答案 4 :(得分:1)

正如其他人提到的,来自MySQL手册。为了实现这一点,您可以使用无符号big int的最大值,即这个可怕的数字(18446744073709551615)。但是,为了使它少一点混乱,可以使用代字号“〜”按位运算符。

  LIMIT 95, ~0

它按位求反。结果“〜0”为18446744073709551615。

答案 5 :(得分:0)

就在今天,我正在阅读从mysql表中获取大量数据(超过一百万行)的最佳方法。正如建议的那样,一种方法是使用LIMIT x,y,其中x是偏移量,y是您想要返回的最后一行。但是,正如我发现的那样,这不是最有效的方法。如果您有自动增量列,则可以轻松地使用带有SELECT子句的WHERE语句,说明您要从哪条记录开始。

例如,     SELECT * FROM table_name WHERE id > x;

当您使用LIMIT时,mysql似乎获得了所有结果,然后只显示适合偏移的记录:不是最佳的性能。

来源:回答这个问题MySQL Forums。请注意,问题大概是6岁。

答案 6 :(得分:0)

您可以使用带有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与执行语句时考虑的表一致。

答案 7 :(得分:0)

我在练习 LC#1321 时遇到了一个非常相似的问题,我必须选择所有日期,但跳过前 6 个日期。

我在 using System; using System.Collections.Generic; using System.Linq; public class Program { public static void Main() { List<string> ListA = new List<string> { "James", "Jon", "Mark", "Jey", "Sara", }; List<string> ListB = new List<string> { "Peter", "Parker", "Bond", "Sara" }; List<string> ListResult = new List<string>(); foreach (var item in ListA) { ListResult.Add(item); } foreach (var item in ListB) { ListResult.Add(item); } ListResult = ListResult.Distinct() .ToList(); foreach(var item in ListResult) { Console.WriteLine(item); } } } 窗口函数和子查询的帮助下在 MySQL 中实现了这一点。例如,以下查询返回前五行跳过的所有结果:

ROW_NUMBER()

您可能需要在子查询中添加更多逻辑,尤其是在 SELECT fieldname1, fieldname2 FROM( SELECT *, ROW_NUMBER() OVER() row_num FROM mytable ) tmp WHERE row_num > 5; 中以满足您的需要。此外,根据您的实际偏移逻辑,可以使用 OVER()/RANK() 窗口函数代替 DENSE_RANK()

参考:

MySQL 8.0 Reference Manual - ROW_NUMBER()

答案 8 :(得分:-1)

我知道这已经过时了,但我没有看到类似的回应,所以这就是我要使用的解决方案。

首先,我将对表执行计数查询以查看存在多少条记录。此查询很快,通常执行时间可以忽略不计。类似的东西:

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”值是没有意义的。

答案 9 :(得分:-6)

WHERE .... AND id > <YOUROFFSET>

id可以是您拥有的任何自动增量或唯一数字列...