2

我有一个专栏

id
-----
1
32
3
6
5
22
54
21

问题1:如何从列中选择除前3条记录之外的所有记录?
问题2:如何选择最后3条记录?

-谢谢。

4

4 回答 4

3

由于LIMIT的一些限制,您基本上需要将此类查询放入存储过程中。您不能在纯 sql 中使用子选择或变量。在存储过程中,您可以使用变量。

这行得通,不幸的是我无法在sqlfiddle中显示它,因为它们似乎对存储过程的支持有限。

drop procedure if exists all_but_3;

delimiter //
create procedure all_but_3()
begin
   declare v_max bigint unsigned default ~0;
   select * from your_table limit 3, v_max;
end//

delimiter ;

drop procedure if exists last_3;
delimiter //
create procedure last_3()
begin
   declare v_max bigint;
   declare v_mid bigint;
   select count(*) from your_table into v_max;
   set v_mid := v_max - 3;
   select * from your_table limit v_mid, v_max;
end//

delimiter ;

call all_but_3();
call last_3();

InnoDB 聚集索引详解

在与@fthiella 讨论了其他答案之一后,我决定详细说明它是如何工作的。

使用 InnoDB 作为引擎的表将始终具有聚集索引。总是。这是他们将数据存储在 InnoDB 中的方式,并且在任何情况下都无法创建没有聚集索引的表。

如果有一个或第一个唯一索引且所有列都设置为非空,InnoDB 将选择主键。如果不存在这样的索引,InnoDB 将创建一个带有行 id 的隐藏列。此行 ID 的工作方式类似于自动增量,如果它有助于将其视为具有自动增量的不可见列,我认为这很好。

InnoDB 将进一步根据使用的索引返回行。它将始终使用一些索引(检索数据的唯一方法是使用二级索引、聚集索引或组合),因此在没有显式创建的索引的情况下,隐藏聚集索引会返回行。

这意味着针对没有主键和唯一索引且所有列都设置为非空且没有 ORDER BY 的表的查询将按照插入的顺序返回行。

这就是这个问题的情况,也是我和许多其他答案的基础。

我并不是说这是处理数据的好方法。在使用此解决方案之前,您应该考虑以下几点:

  • 如果曾经创建过可用作聚集索引的索引,则该表将被重写以使用该索引,并通过这样做对磁盘上的数据进行排序。如果稍后删除索引,则原始插入顺序将丢失并且无法检索。
  • 如果创建了一个索引,即使它不是唯一的,它也可以由优化器选择使用,并且行将按该索引排序。

所有这些都记录在案,对于 5.5,这是此页面上的第三个要点

于 2012-12-29T09:33:02.257 回答
3
  1. 选择除前 3 条记录之外的所有记录:

    从 table1 限制 3 中选择 id,18446744073709551615;

  2. 选择最后 3 条记录:

    select a.id from (select @row_num:=@row_num+1 as RowNumber,id from table1, (select @row_num:=0) x order by RowNumber desc) 作为限制 3;

于 2012-12-29T09:33:43.773 回答
1

使用限制


对于#1,您理论上需要知道行数,但您可以只输入一个巨大的数字:

SELECT bleh FROM blah LIMIT 3, 18446744073709551615

(18446744073709551615 是可能的最大数量——感谢亚历克斯瓦西向我指出这一点


对于#2,您确实需要知道记录数:

SELECT bleh FROM blah LIMIT NUM-3, 3

您必须从单独的查询中获取行数(这应该是 NUM 所在的位置)。


如果有可以排序的条件,则实际上可以在不进行完整计数的情况下执行第二个查询:

SELECT bleh FROM blah ORDER BY field DESC LIMIT 3

我假设情况并非如此。


(如果您不想对表进行计数,另一种选择是只提取所有数据并忽略代码域 [PHP、C 等] 中的前 3 行或最后 3 行。)

于 2012-12-29T09:03:02.843 回答
-1

试试这个:

totalCounts = SELECT COUNT(*) FROM tbl;

SELECT * FROM tbl LIMIT 3,totalCounts
# Retrieve rows 4 to number of table rows
于 2012-12-29T09:13:05.190 回答