limit
引言:
某些情况下,用户可能并非对查询返回的所有结果都感兴趣。例如,构造一个查询返回银行所有柜员及其开立的账户数,但是如果用户只为了查询前三名柜员,从而对其进行奖励,那么久不必知道谁是第四名,第五名。为了解决这个问题,MySQL的select语句包括了limit子句,它允许用户限制查询返回的行数。
-
只有一个参数时的简单查询
-
首先构造查询,返回银行中每个柜员开立的账户数:
SELECT open_emp_id, COUNT(*) how_many FROM account GROUP BY open_emp_id;
-
返回结果:
+-------------+----------+ | open_emp_id | how_many | +-------------+----------+ | 1 | 8 | | 10 | 7 | | 13 | 3 | | 16 | 6 | +-------------+----------+ 4 rows in set (0.05 sec)
-
结果显示4个不同的柜员开立的账户数,如果想限制结果集到仅3条记录,那么读者可以添加一个limit子句指定只有3条记录被返回:
SELECT open_emp_id, COUNT(*) how_many FROM account GROUP BY open_emp_id LIMIT 3;
-
返回结果:
+-------------+----------+ | open_emp_id | how_many | +-------------+----------+ | 1 | 8 | | 10 | 7 | | 13 | 3 | +-------------+----------+ 3 rows in set (0.00 sec)
由于limit子句(上面查询的第四行)的限制,现在结果集刚好包括3条记录,而第四名柜员(员工ID为16)则被丢弃。
-
-
组合limit子句和order by子句
-
由上面的例子可以限制返回的行数,不过有个小问题,即能不能用户自己选择对这4个中的哪3个感兴趣?回到最开始的引言,为了查询前三位柜员,可以结合order by子句,具体如下:
SELECT open_emp_id, COUNT(*) how_many FROM account GROUP BY open_emp_id ORDER BY how_many DESC LIMIT 3 ;
-
结果如下:
+-------------+----------+ | open_emp_id | how_many | +-------------+----------+ | 1 | 8 | | 10 | 7 | | 16 | 6 | +-------------+----------+ 3 rows in set (0.09 sec)
这个查询与前一个的不同之处在于现在将limit子句应用到有序集。除非用户对任意记录感兴趣,否则,通常都需要组合使用order by子句和limit子句。
由于limit子句应用在所有过滤、分组和排序动作完成后,因此它永远不会改变语句的结果,而只是限制查询返回记录的数目。
-
-
limit子句中可选的第二个参数
-
假设用户的目标不是查找前3位柜员,而是前两位之外的其他所有柜员(比如,要找出一些表现不好的柜员进行惩罚)。对于这些情况,limit语句允许可选的第二个参数。在这种情况下,第一个指定结果集的起始记录(行数),第二个参数指定结果集包含的记录数(行数)。指定起始记录时,请记住:MySQL指定第一个记录序号为0。因此,如果想查找第三好表现好的人,可以如下实现:
SELECT open_emp_id, COUNT(*) how_many FROM account GROUP BY open_emp_id ORDER BY how_many DESC LIMIT 2,1;
-
结果如下:
+-------------+----------+ | open_emp_id | how_many | +-------------+----------+ | 16 | 6 | +-------------+----------+ 1 row in set (0.11 sec)
在上面的例子中,第0个和第1个记录背丢弃了,因而结果集是从第2个记录开始的。由于limit子句的第二个参数是1,所以结果集只包含1个记录。
如果用户希望从第2个位置开始,并且包括所有剩下的记录,那么可以使limit子句中的第二个参数足够大到超过剩下的记录数,在这里就不演示了。
-
-
排名查询
-
包含order by子句和limit子句的查询允许将数据进行排名,故这种排名可以称为排名查询。虽然刚才描述的问题是:如何依据开立的账户数对柜员进行排名,但是排名查询可以应用于不同的问题,例如:
公司2005年销售最好的前5名销售员是谁?
棒球历史上第三大全垒打是谁?
下一本1998年最畅销的书是什么?
我们最滞销的两种冰淇淋是什么?
-
至此,我们已经演示了如何查找前三位柜员,第三个优秀柜员以及前两个柜员以外的所有其他柜员。如果打算做一些相似例子(比如查找最差表现者),那么只需要反转排序顺序即可,例如:
SELECT open_emp_id, COUNT(*) how_many FROM account GROUP BY open_emp_id ORDER BY how_many ASC LIMIT 2;
-
结果如下:
+-------------+----------+ | open_emp_id | how_many | +-------------+----------+ | 13 | 3 | | 16 | 6 | +-------------+----------+ 2 rows in set (0.00 sec)
通过简单的改变排列顺序:
ORDER BY how_many DESC
变为ORDER BY how_many ASC
,即可查询返回表现最差的两个柜员。
-
参考资料:《SQL学习指南》,入门SQL书籍推荐。