子查询又称内部,而包含子查询的语句称之外部查询(又称主查询)。 所有的子查询可以分为两类,即相关子查询和非相关子查询 1> 非相关子查询是独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部查询。 2> 相关子查询的执行依赖于外部查询的数据,外部查询执行一行,子查询就执行一次。 故非相关子查询比相关子查询效率高 --非相关子查询 SELECT EMPNO, LASTNAME FROM EMPLOYEE WHERE WORKDEPT = 'A00' AND SALARY > (SELECT AVG(SALARY) FROM EMPLOYEE WHERE WORKDEPT = 'A00') --相关子查询 SELECT E1.EMPNO, E1.LASTNAME, E1.WORKDEPT FROM EMPLOYEE E1 WHERE SALARY > (SELECT AVG(SALARY) FROM EMPLOYEE E2 WHERE E2.WORKDEPT = E1.WORKDEPT) ORDER BY E1.WORKDEPT
子查询
嵌套子查询,非相关子查询
相关例子
相关子查询
自联接
联合查询
•Union 操作符:将两个或更多个 SELECT 语句的结果合并为一个结果集。
•联合可以指定为如下形式:
SELECT 语句 UNION [ALL] SELECT 语句
使用 ALL 子句表示不删除重复的行。
联合查询注意事项:
- 每个select必须具有相同的列结构
- 兼容列类型(指优先级较低数据类型必须能隐式地转换为较高级的数据类型)和相同数目的列
练习:
使用子查询
/*1:写一条查询语句,返回Orders表中活动的最后一天生成的所有订单。涉及的表:Sales.Orders表。期望的输出:*/orderid orderdate custid empid----------- ----------------------- ----------- -----------11077 2008-05-06 00:00:00.000 65 111076 2008-05-06 00:00:00.000 9 411075 2008-05-06 00:00:00.000 68 811074 2008-05-06 00:00:00.000 73 7
参考SQL:
--answer:select orderid,orderdate,custid,empidfrom Sales.Orders where orderdate in ( select max(orderdate) from Sales.Orders ) /* 1.处理嵌套在外层查询语句里的子查询,应用max函数从表Sales.Orders中查找orderdate最后一天的日期,生成虚拟表VT1, 2.处理嵌套在外层的查询语句,从Sales.Orders表中查找满足where条件orderdate在虚拟表VT1中有相等值的数据,得到虚拟表VT2 3.处理select列表,从虚拟表VT2中查找出custid,orderdate,custid,empid返回虚拟表VT3 */
/*2:写一条查询语句,并返回2008年5月1号(包括这一天)以后没有处理过的订单的雇员。涉及到表:HR.Employees表和Sales.Orders表。期望的输出:*/empid FirstName lastname----------- ---------- --------------------3 Judy Lew5 Sven Buck6 Paul Suurs9 Zoya Dolgopyatova
参考SQL:
--answer:select empid,firstname,lastnamefrom HR.Employees where empid not in( select o.empid from Sales.Orders as o where o.orderdate>='2008-05-01' ) /* 1.处理嵌套在外层查询语句里的子查询,表Sales.Orders别名o 2.查找满足where条件 o.orderdate>='2008-05-01',生成虚拟表VT1 3.从虚拟表VT1中处理select列表,查找出empid生成虚拟表VT2 4.处理嵌套在外层的查询语句,从Sales.Orders表中查找满足where条件empid不在虚拟表VT2中有相等值的数据,得到虚拟表VT3 5.处理select列表从虚拟表VT3中查找empid,firstname,lastname返回虚拟表VT4 */
/*3:写一条查询语句,返回订购了第12号产品的客户。涉及的表:Sales.Customers表和Sales.Orders表。期望的输出:*/custid companyname----------------------------------------48 Customer DVFMB39 Customer GLLAG71 Customer LCOUJ65 Customer NYUHS44 Customer OXFRU51 Customer PVDZC86 Customer SNXOJ20 Customer THHDP90 Customer XBBVR46 Customer XPNIK31 Customer YJCBX87 Customer ZHYOS
参考SQL:
--answer:SELECT custid, companynameFROM Sales.Customers AS C WHERE EXISTS (SELECT * FROM Sales.Orders AS O WHERE O.custid = C.custid AND EXISTS (SELECT * FROM Sales.OrderDetails AS OD WHERE OD.orderid = O.orderid AND OD.ProductID = 12)); /* 1.先处理外层查询,从Sales.Customers表别名C中取出一个元组,将元组相关列值custid传给内层查询 2.执行第一层内层查询,Sales.Orders表别名O中取出一个元组,将元组相关列值custid传给内层查询 3.执行第二层内层查询,Sales.Orders表别名OD应用where子句返回满足条件OD.orderid = O.orderid和 OD.ProductID = 12的值 4.返回到第一层内层查询中,应用where子句返回满足条件O.custid = C.custid和EXISTS条件的值 5.返回到外层查询处理 EXISTS,外查询根据子查询返回的结果集得到满足条件的行 */