嵌套子查询

1. 集合成员资格:

eg: 找出选修了ID为10101的教师所教授的课程段的学生数

select count(distinct id)
from takes
where (course_id, sec_id, semester, year) 
    in (select course_id,sec_id, semester, year 
        from teaches 
        where teach.id=10101);

remarks:

  • 集合跟集合里面的属性会一一对应
  • null跟null会被视为不匹配

2. 集合的比较:

eg: 找出工资至少比biology系某一个教师工资要高的所有教师姓名——用”

select name 
from instructor 
where salary > some (select salary 
                     from instructor 
                     where dept_name='biology');                   

remarks:

  • =some等价于in
  • >some表示“至少比一个大
  • any跟some用法一样

eg:找出平均工资最高的系

select dept_name  
from instructor
group by dept_name
having avg(salary) >= all (select avg(salary)
                            from instructor 
                            group by dept_name);
  • 类似的, >all是“比所有的都大”

3. 空关系测试

  • exist在where的子查询中作为参数使用,非空返回true
  • not exists (B except A) 等价于关系A包含关系B,用于测试子查询结果集中是否不存在元组

4. 重复元组存在测试

eg: 找出所有在2009年最多开设一次的课程

select T.course_id 
from course as T 
where unique (select R.course_id
                from section as R
                where T.course_id=R.course_id and R.year=2009);
--等价于 
select T.course_id 
from course as T 
where 1>= (select count(R.course_id)
                from section as R
                where T.course_id=R.course_id and R.year=2009);

remarks:

  • 如果作为参数的子查询结果里面没有重复的元组,unique 将返回true
  • 可以用not exist 测试在一个子查询的结果中是否存在重复元素

5. from子句中的子查询

eg: 找出所有系中工资总额最大的系

select max(tot_salary)
from (select dept_name, sum(salary)
        from instructor
        group by dept_name) as dept_total(dept_name, tot_salary);

remarks:

  • 哪里用子查询的逻辑是:任何select-from-where表达式返回的结果都是关系,因而可以被插入到select-from-where中任何关系可以出现的位置
  • 如果想在from嵌套的子查询里面用来自from其他关系的属性,有的DB里面支持lateral可以实现

6. with子句

eg: 查出所有工资总额大于所有系平均工资总额的系

with dept_total(dept_name, value) as
    (select dept_name, sum(salary)
    from instructor
    group by dept_name),
    dept_total_avg(value) as 
    (select avg(value)
    from dept_total)
select dept_name
from dept_name, dept_total_avg
where dept_total.value>=dept_total_avg.value;

remarks:

  • with子句提供临时定义关系的方法,只对包含该子句的查询有效
  • 优点是逻辑更清晰,还允许在一个查询内多个地方使用视图定义

7. 标量子查询

  • 当子查询只返回包含单个属性的单个元组时(即只有一行一列),SQL允许其出现在任何单个表达式能出现的地方,比如select中
    原文作者:一闪一闪
    原文地址: https://segmentfault.com/a/1190000015127853
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞