连接查询和子查询

常用的多表连接查询

         内连接(INNER JOIN)

外连接

左外连接   (LEFT JOIN)

右外连接   (RIGHT JOIN)

 

内连接

       //内连接是查询有相同记录的

  内连接使用比较运算符根据每个表的通用列中的值匹配两个表中的行

               

              查询结果            

             

  内连接语句

                     语法:

                           

                     示例:

                           

                    

 

              三表内连接

                     示例:

                            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);

                           

                           

 

              左外连接

                           

                            //无匹配返回NULL

                     示例:

                            SELECT S.studentName,R.subjectNo,R.studentResult

FROM   student AS S

LEFT JOIN result AS R

ON S.studentNo = R.studentNo;

                问题:猜一猜:这样写,返回的查询结果是一样的吗?

                                   SELECT S.studentName,R.subjectNo,R.studentResult

FROM   result AS R

LEFT JOIN student AS S

ON S.studentNo = R.studentNo;

                                   //不一样,主表和从表位置已互换

 

              右外连接

右外连接的原理与左外连接相同

右表逐条去匹配记录;否则NULL填充

                            示例:

                                   SELECT 图书编号,图书名称,出版社名称

FROM 图书表

RIGHT JOIN 出版社表

ON 图书表.出版社编号 = 出版社表.出版社编号;

                                  

              三种连接的对比

                           

 

等值连接和内连接一样!

 

非等值连接

              左边行数乘于右边行数

 

 

什么是子查询

             

              语法:

                     SELECT … FROM 表1 WHERE 字段1  比较运算符(子查询)

              注意:

将子查询和比较运算符联合使用,必须保证子查询返回的值不能多于一个

 

 

IN子查询

  查询“Logic Java”课程考试成绩为60分的学生名单

                    

             

                    

 

 

 

              问题;

查询参加“Logic Java”课程最近一次考试的在读学生名单

              分析:

实现步骤

  1. 获得 “Logic Java”课程的课程编号

SELECT `subjectNo` FROM `subject`

WHERE `subjectName`='Logic Java';

  1. 根据课程编号查询得到“Logic Java”课程最近一次的考试日期

SELECT MAX(`examDate`) FROM `result` WHERE `subjectNo`= (

SELECT `subjectNo` FROM `subject`

WHERE `subjectName`='Logic Java' );

  1. 根据课程编号和最近一次的考试日期查询出在读学生信息  

 

 

参考语句

 

 

NOT IN子查询

                     问题

                查询未参加“Logic Java”课程最近一次考试的在读学生名单

                     分析:

                 实现步骤

      1. 查询参加“Logic Java”课程最近一次考试的学生名单
      2. 在IN关键字之前增加否定词NOT
      3. 限定“Logic Java”课程所在学期

      

                            SELECT `studentNo`, `studentName` FROM `student` WHERE `studentNo`

NOT IN(

  SELECT `studentNo` FROM `result`

  WHERE `subjectNo` = (     

      SELECT `subjectNo` FROM `subject`

      WHERE `subjectName`='Logic Java'

   ) AND `examDate` = (       

        SELECT MAX(`examDate`) FROM `result`  WHERE `subjectNo` = (  

             SELECT `subjectNo` FROM `subject`

             WHERE `subjectName`='Logic Java')

   )

)……

                                  

 

 

EXISTS子查询

 

 

 

 

              问题:

         如何用SQL语句检测temp表是否已经创建?

                     DROP TABLE IF EXISTS temp;

CREATE TABLE temp (

                 … … #省略建表语句

) ;

                     EXISTS关键字是否还有其他用法?

              语法:

         EXISTS子查询的语法;

                     SELECT …… FROM 表名 WHERE EXISTS(子查询);

子查询有返回结果: EXISTS子查询结果为TRUE

子查询无返回结果: EXISTS子查询结果为FALSE,

                                     外层查询不执行

 

 

参考语句:

              SELECT AVG(studentresult)+5 AS 平均分 FROM result

WHERE NOT EXISTS (

SELECT * FROM `result`  WHERE `subjectNo` = (

   SELECT `subjectNo` FROM `subject` WHERE `subjectName` = 'Logic Java'

  )  AND `examDate` = (

     SELECT MAX(`examDate`) FROM `result` WHERE `subjectNo` = (    

       SELECT `subjectNo` FROM `subject`

       WHERE `subjectName` = 'Logic Java')

  ) AND `studentResult` > 60)

AND `subjectNo` = ( SELECT `subjectNo` FROM `subject`

WHERE `subjectName` = 'Logic Java')

AND `examDate` = (

  SELECT MAX(`examDate`) FROM `result` WHERE `subjectNo` = (    

  SELECT `subjectNo` FROM `subject`

  WHERE `subjectName` = 'Logic Java') );

 

子查询注意事项

  1. 任何允许使用表达式的地方都可以使用子查询
  2. 嵌套在父查询SELECT语句的子查询可包括
    1. SELECT子句
    2. FROM子句
    3. WHERE子句
    4. GROUP BY子句
    5. HAVING子句
  3. 只出现在子查询中而没有出现在父查询中的列不能包含在输出列中

//WHERE子句 GROUP BY 子句 HAVING 子句  是可选子句,根据雨雾需求决定

 

 

示例:学员操作——制作学生成绩单

              指导

         训练要点

任何允许使用表达式的地方都可以使用子查询

         需求说明

为每个学生制作在校期间每门课程的成绩单,要求每个学生参加每门课程的最后一次考试成绩作为该生本课程的最终成绩

成绩单的数据项

学生姓名

课程所属的年级名称

课程名称

考试日期

考试成绩

 

分组查询用法

                     语法:

                            掌握GROUP BY子句实现分组查询

                            SELECT …… FROM  <表名> 

WHERE  ……

GROUP BY ……

                           

 

分组查询解析

         问题:查询每门课程的平均分,并且按照分数由高到低的顺序排列显示

                     SELECT `subjectNo`,AVG(`studentResult`) AS 课程平均成绩

FROM `result`

GROUP BY `subjectNo`

ORDER BY AVG(`studentResult`);

                    

 

多列分组

              分别统计每个年级男、女生人数

                     SELECT `gradeId` AS 年级编号,`sex` AS 性别,COUNT(*) AS 人数

FROM `student`

GROUP BY `gradeId`,`sex`

ORDER BY `gradeId`;

                    

  如何获得课程平均分及格的课程编号?

                    

 

分组筛选

              分组筛选语句

                     语法:

SELECT …… FROM  <表名>

WHERE ……

GROUP BY ……

HAVING……

                     示例:

                            SELECT `subjectNo`,AVG(`studentResult`) AS 课程平均成绩

FROM `result`

GROUP BY `subjectNo`

HAVING AVG(`studentResult`) >=60;

 

WHERE与HAVING对比

  1.          WHERE子句

用来筛选 FROM 子句中指定的操作所产生的行

  1. GROUP BY子句

用来分组 WHERE 子句的输出

  1. HAVING子句

用来从分组的结果中筛选行

 

              问题:如何同时从这两个表中取得数据?

                    

 

常用的多表连接查询

              内连接(INNER JOIN)

 外连接

    1. 左外连接   (LEFT JOIN)
    2. 右外连接   (RIGHT JOIN)

 

 

总结

 

 

                    

                    

猜你喜欢

转载自blog.csdn.net/luvhl711/article/details/82959264