zoukankan      html  css  js  c++  java
  • sql--查询(分页,聚合)

    分页

    使用SELECT查询时,如果结果集数据量很大,比如几万行数据,放在一个页面显示的话数据量太大,不如分页显示,每次显示100条。
    要实现分页功能,实际上就是从结果集中显示第1100条记录作为第1页,显示第101200条记录作为第2页,以此类推。
    因此,分页实际上就是从结果集中“截取”出第M~N条记录。这个查询可以通过LIMIT OFFSET 子句实现。我们先把所有学生按照成绩从高到低进行排序:
    -- 按score从高到低

    SELECT id, name, gender, score FROM students ORDER BY score DESC;

    现在,我们把结果集分页,每页3条记录。要获取第1页的记录,可以使用LIMIT 3 OFFSET 0:

    -- 查询第1页

    SELECT id, name, gender, score
    FROM students
    ORDER BY score DESC
    LIMIT 3 OFFSET 0;

    上述查询LIMIT 3 OFFSET 0表示,对结果集从0号记录开始,最多取3条。注意SQL记录集的索引从0开始。

    如果要查询第2页,那么我们只需要“跳过”头3条记录,也就是对结果集从3号记录开始查询,把OFFSET设定为3:

    -- 查询第2页

    SELECT id, name, gender, score
    FROM students
    ORDER BY score DESC
    LIMIT 3 OFFSET 3;

    类似的,查询第3页的时候,OFFSET应该设定为6:

    -- 查询第3页

    SELECT id, name, gender, score
    FROM students
    ORDER BY score DESC
    LIMIT 3 OFFSET 6;

    查询第4页的时候,OFFSET应该设定为9:

    -- 查询第4页

    SELECT id, name, gender, score
    FROM students
    ORDER BY score DESC
    LIMIT 3 OFFSET 9;

    由于第4页只有1条记录,因此最终结果集按实际数量1显示。LIMIT 3表示的意思是“最多3条记录”。

    可见,分页查询的关键在于,首先要确定每页需要显示的结果数量pageSize(这里是3),然后根据当前页的索引pageIndex(从1开始),确定LIMIT和OFFSET应该设定的值:

    LIMIT总是设定为pageSize;
    OFFSET计算公式为pageSize * (pageIndex - 1)。
    这样就能正确查询出第N页的记录集。

    如果原本记录集一共就10条记录,但我们把OFFSET设置为20,会得到什么结果呢?

    -- OFFSET设定为20

    SELECT id, name, gender, score
    FROM students
    ORDER BY score DESC
    LIMIT 3 OFFSET 20;

    OFFSET超过了查询的最大数量并不会报错,而是得到一个空的结果集。

    注意
    OFFSET是可选的,如果只写LIMIT 15,那么相当于LIMIT 15 OFFSET 0。

    在MySQL中,LIMIT 15 OFFSET 30还可以简写成LIMIT 30, 15。

    使用LIMIT OFFSET 分页时,随着N越来越大,查询效率也会越来越低。

    小结
    使用LIMIT OFFSET 可以对结果集进行分页,每次查询返回结果集的一部分;

    分页查询需要先确定每页的数量和当前页数,然后确定LIMIT和OFFSET的值。

    聚合查询

    如果我们要统计一张表的数据量,例如,想查询students表一共有多少条记录,难道必须用SELECT * FROM students查出来然后再数一数有多少行吗?

    这个方法当然可以,但是比较弱智。对于统计总数、平均数这类计算,SQL提供了专门的聚合函数,使用聚合函数进行查询,就是聚合查询,它可以快速获得结果。

    仍然以查询students表一共有多少条记录为例,我们可以使用SQL内置的COUNT()函数查询:

    -- 使用聚合查询:

    SELECT COUNT(*) FROM students;

    COUNT()表示查询所有列的行数,要注意聚合的计算结果虽然是一个数字,但查询的结果仍然是一个二维表,只是这个二维表只有一行一列,并且列名是COUNT()。

    通常,使用聚合查询时,我们应该给列名设置一个别名,便于处理结果:

    -- 使用聚合查询并设置结果集的列名为num:

    SELECT COUNT(*) num FROM students;

    COUNT(*)和COUNT(id)实际上是一样的效果。另外注意,聚合查询同样可以使用WHERE条件,因此我们可以方便地统计出有多少男生、多少女生、多少80分以上的学生等:

    -- 使用聚合查询并设置WHERE条件:

    SELECT COUNT(*) boys FROM students WHERE gender = 'M';

    除了COUNT()函数外,SQL还提供了如下聚合函数:

    函数 说明
    SUM 计算某一列的合计值,该列必须为数值类型
    AVG 计算某一列的平均值,该列必须为数值类型
    MAX 计算某一列的最大值
    MIN 计算某一列的最小值

    注意,MAX()和MIN()函数并不限于数值类型。如果是字符类型,MAX()和MIN()会返回排序最后和排序最前的字符。

    要统计男生的平均成绩,我们用下面的聚合查询:

    -- 使用聚合查询计算男生平均成绩:

    SELECT AVG(score) average FROM students WHERE gender = 'M';

    要特别注意:如果聚合查询的WHERE条件没有匹配到任何行,COUNT()会返回0,而SUM()、AVG()、MAX()和MIN()会返回NULL:

    -- WHERE条件gender = 'X'匹配不到任何行:

    SELECT AVG(score) average FROM students WHERE gender = 'X';

    分组

    如果我们要统计一班的学生数量,我们知道,可以用SELECT COUNT(*) num FROM students WHERE class_id = 1;。如果要继续统计二班、三班的学生数量,难道必须不断修改WHERE条件来执行SELECT语句吗?

    对于聚合查询,SQL还提供了“分组聚合”的功能。我们观察下面的聚合查询:

    -- 按class_id分组:

    SELECT COUNT(*) num FROM students GROUP BY class_id;

    执行这个查询,COUNT()的结果不再是一个,而是3个,这是因为,GROUP BY子句指定了按class_id分组,因此,执行该SELECT语句时,会把class_id相同的列先分组,再分别计算,因此,得到了3行结果。

    但是这3行结果分别是哪三个班级的,不好看出来,所以我们可以把class_id列也放入结果集中:

    -- 按class_id分组:

    SELECT class_id, COUNT(*) num FROM students GROUP BY class_id;

    这下结果集就可以一目了然地看出各个班级的学生人数。我们再试试把name放入结果集:

    -- 按class_id分组:

    SELECT name, class_id, COUNT(*) num FROM students GROUP BY class_id;

    不出意外,执行这条查询我们会得到一个语法错误,因为在任意一个分组中,只有class_id都相同,name是不同的,SQL引擎不能把多个name的值放入一行记录中。因此,聚合查询的列中,只能放入分组的列。

    注意:AlaSQL并没有严格执行SQL标准,上述SQL在浏览器可以正常执行,但是在MySQL、Oracle等环境下将报错,请自行在MySQL中测试。
    也可以使用多个列进行分组。例如,我们想统计各班的男生和女生人数:

    -- 按class_id, gender分组:

    SELECT class_id, gender, COUNT(*) num FROM students GROUP BY class_id, gender;

    上述查询结果集一共有6条记录,分别对应各班级的男生和女生人数。

  • 相关阅读:
    linq——group by
    WebApi——json返回多了 k_BackingField
    Fiddler使用
    iis发布,部署
    项目梳理7——Nuget包管理
    CVS导出&&自定义Attribute的使用
    项目梳理6——使用WebApiTestClient为webapi添加测试
    项目梳理5——修改已生成.nuspec文件
    项目梳理4——WebApi项目,使用注释填充Description字段
    jQuery object and DOM Element
  • 原文地址:https://www.cnblogs.com/HK769405/p/13997735.html
Copyright © 2011-2022 走看看