我有一个专栏
id
-----
1
32
3
6
5
22
54
21
问题1:除了前3条记录外,如何从列中选择所有记录?
问题2:如何选择最后3条记录?
-Thanks。
答案 0 :(得分:3)
由于stored procedures的某些限制,您基本上需要将此类查询放入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();
在与@fthiella的其他一个答案讨论后,我决定详细说明这是如何工作的。
使用InnoDB作为引擎的表将始终具有聚簇索引。总是。这是他们将数据存储在InnoDB中的方式,并且以任何方式创建没有聚集索引的表都没有。
如果存在一个或第一个唯一索引且所有列都设置为非空,InnoDB将选择主键。如果不存在这样的索引,InnoDB将创建一个带有行ID的隐藏列。这行id与自动增量类似,如果它有助于将其视为具有自动增量的不可见列,我认为这很好。
InnoDB还将根据使用的索引返回行。它总是使用一些索引(只有检索数据的方法是使用二级索引,聚簇索引或组合)所以在没有显式创建索引的情况下,隐藏聚簇索引返回行。
这意味着对没有主键且没有唯一索引的表的查询将所有列设置为非null且没有ORDER BY将按插入顺序返回行。
这是问题的基础,也是我的基础和许多其他答案。
我并不是说这是处理数据的好方法。在使用此解决方案之前,您应该考虑以下事项:
所有这些都记录在案,对于5.5,它是this page
上的第3个要点答案 1 :(得分:3)
选择除前3个记录以外的所有记录:
从table1 limit 3,18446744073709551615中选择id;
选择最后3条记录:
选择a.id(选择@row_num:= @ row_num + 1作为RowNumber,id来自table1,(选择@row_num:= 0)x order by RowNumber desc)作为限制3;
答案 2 :(得分:1)
使用LIMIT
对于#1,理论上你需要知道行数,但你只需要输入一个大数字:
SELECT bleh FROM blah LIMIT 3, 18446744073709551615
(18446744073709551615是可能的最大数量 - 感谢alex vasi指示我this)
对于#2,你确实需要知道记录的数量:
SELECT bleh FROM blah LIMIT NUM-3, 3
您必须从单独的查询中获取行数(应该是NUM所在的位置)。
如果有可以排序的标准,您实际上可以在不进行完整计数的情况下进行第二次查询:
SELECT bleh FROM blah ORDER BY field DESC LIMIT 3
我认为情况并非如此。
(如果您不想对表进行计数,另一个选择是只提取所有数据并忽略code-land [PHP,C等]中的第一行或最后3行。)
答案 3 :(得分:-1)
试试这个:
totalCounts = SELECT COUNT(*) FROM tbl;
SELECT * FROM tbl LIMIT 3,totalCounts
# Retrieve rows 4 to number of table rows