MySQL对SQL语言的扩展——limit

作者: 廖少少 | 来源:发表于2016-10-14 10:59 被阅读240次

    limit


    引言:

    某些情况下,用户可能并非对查询返回的所有结果都感兴趣。例如,构造一个查询返回银行所有柜员及其开立的账户数,但是如果用户只为了查询前三名柜员,从而对其进行奖励,那么久不必知道谁是第四名,第五名。为了解决这个问题,MySQL的select语句包括了limit子句,它允许用户限制查询返回的行数

    1. 只有一个参数时的简单查询

      • 首先构造查询,返回银行中每个柜员开立的账户数:

          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)则被丢弃。

    2. 组合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子句应用在所有过滤、分组和排序动作完成后,因此它永远不会改变语句的结果,而只是限制查询返回记录的数目。

    3. 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子句中的第二个参数足够大到超过剩下的记录数,在这里就不演示了。

    4. 排名查询

      • 包含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书籍推荐。

    相关文章

      网友评论

        本文标题:MySQL对SQL语言的扩展——limit

        本文链接:https://www.haomeiwen.com/subject/qjmgyttx.html