• SQL复杂查询和视图


    子查询

    现实中,很多情况下需要进行下述条件判断

    • 某一元素是否是某一集合成员
    • 某一集合是否包含另一集合
    • 测试集合是否为空
    • 测试集合是否存在另一元组

    子查询是出现在WHERE子句中的SELECT语句被称为子查询,子查询返回了一个集合。

    IN子查询

    基本语法:查询语句 [NOT] IN 子查询

    语义:查询语句产生的结果是否在子查询当中

    • 列出选修了001号课程的学生学号和姓名

    SELECT sn, sname
    FROM student
    WHERE sn IN (SELECT sn FROM sc WHERE cn="001");

    括号中产生的结果是一个集合(这里称为子集合),集合中的元素是学过001课程的学生的学号。前半部分的查询语句是从student中每取一条记录来查看记录中的sn是否在子集合中。如果是则将该记录进行标记,否则取出下一条继续比较。最后将被标记的记录中sn和snames属性值输出。

    image

    • 查询既学过001课程又学过002课程的同学学号

    SELECT sn
    FROM sc
    WHERE cn="001" AND sn IN (SELECT sn FROM sc WHERE cn="002");

    image

    非相关子查询

    查询分为外层查询和内层查询

    image

    外层查询的参数可以被带入到内层查询中,而内层查询的参数不能在外层查询中使用,这和高级编程中的循环一个道理。

    当内层查询没有使用到外查询的参数时,我们可以内层查询是非相关子查询。上图中就是非相关子查询。判断是否相关最简单的方式就是内层查询是否能独立执行。

    相关子查询

    image

    上图的例子中内层子查询使用到了外层的变量(Stud),这样内层查询就不能独立执行

    SOME与ALL子查询

    基本语法:查询语句 Θ SOME 子查询

                  查询语句 Θ ALL 子查询

    Θ 是运算符:<,>,<=,>=,<>

    Θ SOME表示前面的记录需要与子查询结果中某个记录做运算,如果为TRUE则该记录被接受

    Θ ALL表示前面的记录需要与子查询结果中所有记录做运算,如果全为TRUE则该记录才被接受

    • 找出工资最低的教师姓名

    SELECT tname
    FROM teacher
    WHERE salary <= ALL(
        SELECT salary
        FROM teacher)

    image

    • 找出001号课成绩不是最高的所有学生的学号

    SELECT sn
    FROM sc
    WHERE cn="001" AND score < SOME(
        SELECT score
        FROM sc
        WHERE cn = "001")

    image

    • 找出所有成绩都不及格的学生姓名(相关查询)

    SELECT sname
    FROM student
    WHERE 60 > ALL(
        SELECT score
        FROM sc
        WHERE sc.sn = student.sn)

    image

    • 找出张三同学成绩最低的课程号

    SELECT cn
    FROM sc,student
    WHERE sname="张三" AND sc.sn=student.sn AND score <=ALL(
        SELECT score
        FROM sc
        WHERE sn=student.sn)

    image

    EXISTS查询

    基本语法: [NOT] EXISTS (子查询)

    含义:判断子查询结果集是否为空,当子查询为空时,EXISTS判断为false,而NOT EXISTS判断为true。NOT EXISTS使用情况比较多

    • 检索学过001号教师主讲的所有课程的同学姓名

    等价转换为不存在这样一门课程,该课程由001教师主讲并且该课程该同学没学过

    SELECT sname
    FROM student
    WHERE NOT EXISTS(
        SELECT *
        FROM course
        WHERE tn="001" AND NOT EXISTS(
            SELECT *
            FROM sc
            WHERE sn=student.sn AND cn=course.cn)
        )

    • 列出没有学过李明老师课的学生姓名

    等价于不存在这样的学生,他学过李明老师的课

    SELECT sname
    FROM student
    WHERE NOT EXISTS(
        SELECT *
        FROM course,sc,teacher
        WHERE course.cn=sc.cn AND teacher.tn=course.tn AND tname="李明" AND student.sn=sc.sn)

    • 列出至少学过98030101号同学学过所有课程的同学学号

    等价于不存在98030101同学学过的课程,该同学没有学过

    SELECT sn
    FROM sc AS sc1
    WHERE sn !="98030101" AND NOT EXISTS(
         SELECT *
         FROM sc AS sc2
         WHERE sn="98030101" NOT EXISTS(
            SELECT *
            FROM sc AS sc3
            WHERE sc2.cn=cn AND sn=sc1.sn)
        )

    image

    结果计算与聚类计算

    结果计算和聚类计算是对查询结果集中的一些数据进行计算

    • 求任意两名教师的薪水差额(差额>0)

    SELECT t1.tname AS teacher1, t2.tname AS teacher2,t1.salary-t2.salary
    FROM teacher AS t1, teacher AS t2
    WHERE t1.salary >t2.salary

    image

    聚类计算

    image

    • 求教师工资总和

    SELECT SUM(salary)
    FROM teacher

    image

    • 求数据库课程的平均成绩

    SELECT AVG(score)
    FROM sc,course
    WHERE sc.cn=course.cn AND course.cname="数据库"

    image

  • 相关阅读:
    mybatis动态sql和分页
    mybatis入门
    IDEA
    Linux环境搭建
    svn
    jwt
    Vuex
    SPA项目开发之CRUD+表单验证
    JavaScript可视化框架——Echarts
    python+selenium六:隐式等待
  • 原文地址:https://www.cnblogs.com/xidongyu/p/5993568.html
Copyright © 2020-2023  润新知