简介:嵌入在其他SQL语句中的SELECT语句称为子查询。为在多个SELECT语句的结果集上进行集合操作,可以使用集合操作UNION、
UNION ALL、INTERSECT和MINUS。
一、子查询
1.单行子查询
只返回一行一旬数据的子查询被称为单行子查询。
(1)在WHERE子句中使用子查询
在WHERE子句中使用子查询时,可以使用单行比较符=、<>、<、>、<=、>=等。
在这种情况下,子查询的结果作为主查询的查询条件。
SELECT * FROM teachers
WHERE wage < (SELECT AVG(wage) FROM teachers);
SELECT * FROM students
WHERE specialty = (
SELECT specialty FROM students
WHERE name = '高山');
SELECT * FROM students
WHERE dob > (
SELECT dob FROM students
WHERE name = '高山');
(2)在HAVING子句中使用子查询
在HAVING子句中使用子查询时,该子查询的结果作为主查询分组条件。
SELECT department_id, AVG(wage) AS 平均工资
FROM teachers
GROUP BY department_id
HAVING AVG(wage) > (
SELECT MIN(AVG(wage))
FROM teachers
GROUP BY department_id
);
(3)在FROM子句中使用子查询
--在FROM子句中使用子查询时,该子查询的结果作为主查询的视图。
SELECT * FROM (SELECT * FROM students WHERE sex = '男')
WHERE specialty = '计算机';
2.多行子查询
返回多行单列数据的子查询被称为多选子查询。当在WHERE子句中使用多选子查询时,
必须要使用多行比较符IN、ANY或ALL。
- Some在此表示满足其中一个的意义,是用or串起来的比较从句。
- Any也表示满足其中一个的意义,也是用or串起来的比较从句,区别是any一般用在非“=”的比较关系中,这也很好理解,英文中的否定句中使用any肯定句中使用sone,这一点是一样的。
- All则表示满足其其中所有的查询结果的含义,使用and串起来的比较从句。
(1)在多行子查询中使用IN或NOT IN操作符。
SELECT student_id, name FROM students
WHERE student_id IN(
SELECT student_id FROM students
WHERE name LIKE '王%');
SELECT course_id, course_name FROM courses
WHERE course_id NOT IN(
SELECT course_id FROM Students_grade);
(2)在多行子查询中使用ANY操作符(平均工资比任意一个部门的老师的平均工资低的老师)
SELECT * FROM teachers
WHERE wage < ANY (SELECT AVG(wage) FROM teachers GROUP BY department_id);
(3)在多行子查询中使用some操作符(平均工资等于任意一个部门的老师的平均工资的老师)
SELECT * FROM teachers
WHERE wage = some(SELECT AVG(wage) FROM teachers GROUP BY department_id);
(4)在多行子查询使用ALL操作符
SELECT * FROM teachers
WHERE wage > ALL(
SELECT AVG(wage)
FROM teachers
GROUP BY department_id);
3.多列子查询
多列子查询是指返回多列(单行或多行)数据的子查询语句。返回单行多列数据的子查询,可以参照单行子查询的例子
来编写查询语句;返回多行多列数据的子查询,可以参照多行子查询的例子来编写查询语句。
SELECT * FROM students
WHERE (specialty, dob) = (
SELECT specialty, dob FROM students WHERE name = '高山'
);
SELECT * FROM teachers
WHERE (department_id, wage) IN(
SELECT department_id, Min(wage)
FROM teachers GROUP BY department_id
);
4.相关子查询
有时,子查询引用了外部(主)查询中包含的一列或多列,子查询不能在外部(主)查询之前求值,
需要依靠外部查询才能获得值,这样的子查询被称为相关子查询。
SELECT * FROM teachers t1
WHERE wage > (
SELECT AVG(wage) FROM teachers t2
WHERE t2.department_id = t1.department_id
);
(1)使用EXISTS
这里面的EXISTS是如何运作呢?子查询返回的是OrderId字段,可是外面的查询要找的是CustomerID和CompanyName字段,这两个字段肯定不在OrderID里面啊,这是如何匹配的呢?
EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False。
EXISTS 指定一个子查询,检测行的存在。语法:EXISTS subquery。参数 subquery 是一个受限的 SELECT 语句 (不允许有 COMPUTE 子句和 INTO 关键字)。结果类型为 Boolean,如果子查询包含行,则返回 TRUE。
SELECT course_id, course_name FROM courses c
WHERE EXISTS(
SELECT 2 FROM students_grade sg
WHERE sg.course_id = c. course_id
);
(2)使用NOT EXISTS
SELECT course_id, course_name FROM courses c
WHERE NOT EXISTS(
SELECT 2 FROM students_grade sg
WHERE sg.course_id = c.course_id
);
(3)使用IN
SELECT department_id, department_name FROM departments
WHERE department_id IN(
SELECT department_id FROM teachers
);
(4)使用NOT IN
SELECT department_id, department_name FROM departments
WHERE department_id NOT IN(
SELECT department_id FROM teachers
);
5.嵌套子查询
SELECT * FROM (
SELECT * FROM students
WHERE specialty = (
SELECT specialty FROM students
WHERE name = '高山'
)
);