• MySQL高级查询


    1、exists和not exists子查询

    /*exists的常用用法*/
    drop table if exists student;

      此外,exists也可以作为where的子查询:

    /*exists的参数是一个任意的子查询*/
    /*若有返回行,exists的结果为true,会执行外层语句*/
    /*若无返回行,exists结果为false,外层语句不再执行*/
    select colums from tableName where exists(子查询);

      注意,exists和not exists的结果只取决于是否有返回记录,不取决于记录的内容。

      2、子查询注意事项

      (1)子查询语句可以嵌套在SQL语句中任何表达式出现的位置

      子查询可以被嵌套在select语句的列、表和查询条件中,即select子句、from子句、where子句、group by子句和having子句。

    复制代码
    /*select子句*/
    select(子查询)from 表名;
    
    /*from子句*/
    /*这里表的别名不能省略*/
    select * from(子查询 )as 表的别名;
    复制代码

      (2)只出现在子查询中而没有出现在父查询中的表不能包含在输出列中;

      3、分组查询

      (1)group by——将查询结果按照一个、多个字段分组

    /*单独使用group by*/
    select * from student group by major

      当像上面那样单独使用group by时,结果中每一个不同的major只会显示一个(即每组中挑选一个显示,貌似为每组的第一个)。这样是没有太多意义的,或者说,它只显示了有多少个不同的major。

      所用我们在分组查询中会与数学统计函数结合一起使用。

      单字段分组查询:

    复制代码
    /*查看每门课程的平均成绩*/
    select subjectNo,AVG(studentResult) as 课程平均成绩
        from result group by subjectNo;
    
    /*查询男、女学生的人数各是多少*/
    /*这里的可以这样使用*号吗?为何不直接指明列名?*/
    /*可见的是表中的一行就仅代表一个人,所以这里用*表示的是对这种情况按行统计*/
    select count(*) as 人数,sex from student group by sex;
    
    /*查询每个年级的人数*/
    /*这里的count(*)也是一样*/
    select count(*) as 年纪人数,gradeId from student group by gradeId;
    
    /*查询每个科目的平均分,并且按照由高到低的顺序排列显示*/
    /*这里要思考的是order by的位置,注意要对哪个数据排序*/
    select subjectN,AVG(studentResult) AS 平均课程成绩
       from result
       group by subjectNo;
       order by AVG(studentResult) desc;
    复制代码

      多字段分组查询:

    /*在一张学生信息表中有来自不同年纪、不同性别的学生,学号也都不同*/
    /*现在统计每个年纪的男、女生人数*/
    select count(*) as 人数,gradeId as 年级,sex as 性别 from student
        group by gradeId,sex
        order by gradeId;

      注意到了,使用group by关键字时,在select列表中可以指定的列是有限制的,仅允许group by子句后的列,聚合函数计算出的列。

      4、使用having子句进行分组筛选

      简单来说,having子句用来对分组后的数据进行筛选,即将组看成新的列,来进行筛选。而where子句只能对没有分组统计前的数据进行筛选。

      (1)查询年纪总人数超过1的年级——先按年级分组,再按条件筛选

    select count(*) as 人数,gradeId as 年级 from student 
        group by grade
        having count(*)>2;

      (2)select语句中,where、group by、having子句和聚合函数的执行次序如下:

      where子句从数据源中去除不符合条件的数据;然后group by子句搜集数据行到各个组中;

      接着统计函数为各个组计算统计值;最后having子句去掉不符合其组搜索条件的各组数据行。

      如,查询每门课程及格总人数和及格平均分在80分以上的记录:

    select count(*) as 人数,AVG(studentResult) as 平均分,subjectNo as 课程 from result
        where studentResult>=60
        group by subjectNo
        having AVG(studentResult)>=80;

      5、使用limit分页查询数据——基于多个表的数据查询

      (1)多表连接查询——从多个表中选择or比较数据项

        通过各个表之间共同列的关联性查询数据,是关系数据库查询最主要的特征。

      (2)内连接查询,最典型、常用的连接查询,根据表中共同的列来进行匹配。特别当两个表存在主、外键关系时通常使用内连接查询。

      (3)外连接查询,至少返回一个表中的所有记录,根据匹配条件有选择性地返回另一张表的记录。有左外连接、右外连接。

      6、内连接查询

      内连接通常使用“=”or“<>”等比较运算符来判断两列数据值是否相等。

      在内连接查询中,参与的表的地位是相等的。

      实现内连接的两种方式:

      (1)where子句中指定连接条件

    /*查询学生姓名和成绩,成绩表中只有学号和成绩,名字在学生信息表中*/
    /*from后面有两个表名*/
    select student.studentName,result.subjectNo,result.studentResult
        from student,result
        where student.studentNo=result.studentNo;

      (2)在from子句中使用inner join...on

    复制代码
    /*inner join连接两个表,且inner可以省略*/
    /*on设置条件*/
    /*as指定表的别名,如果查询的列名在多个表中的名字不重复,则可以不使用表名限定*/
    select S.studentName,R.subjectNo,R.studentResult
      from student as S
      inner join result as R on(S.studentNo=R.studentNo)
    
    /*连接三个表*/
    /*查询的数据分别来自三个表*/
    select S.studentName as 学生姓名,SU.subjectName as 课程名称,
        R.studentResult as 考试成绩 
        from student as S
        inner join result as R on(S.studentNo=R.studentNo)
        inner join subject as SU on(SU.subjectNo=R.subjectNo)
    复制代码

      7、外连接查询

      参与外连接查询的表有主、从之分,以主表的每行数据匹配从表的数据列,将符合连接条件的数据直接返回到结果集中;而对不符合连接条件的列,会填上null值后再返回到结果集中。(内连接中会忽略不符合条件的数据)

      (1)左外连接——left join...on,left outer join...on

      结果集包括left join中指定的左表的所有行,若左表的某行在右表中没有匹配行,则在相关的结果集行中右表的所有选择列为空值。

    复制代码
    /*显示所有考试名单上的学生的成绩,没有参加的也要打印出来*/
    /*主表(左表)为学生信息表,学生成绩表为从表*/
    /*没有参加任何科目考试的学生,在成绩表中也没有相关记录*/
    /*他们对应的科目编号和成绩均会以null填充*/
    select S.studentName,R.subjectNo,R.studentResult
      from student as S
      left outer join result as R on(S.studentNo=R.studentNo)
    复制代码

      (2)右外连接——right outer join...on,right outer join...on

      结果集要包含右表中所有匹配的行,若右表中有的项在左表中没有对应的项,以null值填充。

      在这里,join指定的表为主表,即右表为主表。(哪个表中所有行都显示了,就是主表)

  • 相关阅读:
    [转] 数学原理浅谈一下《黑客帝国》
    [转] 应聘Java笔试时可能出现问题及其答案(第八部分)
    经典排序之堆排序
    求全排列算法简单的实现
    求一个整数因式分解
    adk环境变量配置
    经典排序之希尔排序
    快速求幂算法
    判断一个数字是否为素数的基于C语言的算法
    高次幂求模
  • 原文地址:https://www.cnblogs.com/cute9406/p/11714237.html
Copyright © 2020-2023  润新知