06.子查询

01返回单行的子查询

SELECT STU.*
FROM STU
WHERE AGE = (SELECT AGE FROM STU WHERE NAME = '林琳');

SELECT STU.*
FROM STU
WHERE AGE >= (SELECT AVG(AGE) FROM STU);

 

SELECT *
FROM STU
WHERE NO = (SELECT NO FROM GRADE WHERE SCORE = 85);
--OR
SELECT S.*
FROM STU S INNER JOIN GRADE G
ON S.NO = G.NO
WHERE G.SCORE = 85;
--使用单行子查询时,一定要确认子查询只能返回单个值
--否则使用>,<,=,>=,<=,<>运算符将会报错

02用IN实现多行子查询

SELECT STU.*
FROM STU
WHERE DEPT IN(SELECT DEPT FROM STU WHERE NAME = '陈诚');

SELECT STU.*
FROM STU
WHERE NO NOT IN(SELECT NO FROM GRADE WHERE SCORE < 90)
AND NO IN(SELECT NO FROM GRADE);
--OR
SELECT STU.*, GRADE.*
FROM STU INNER JOIN GRADE
ON STU.NO = GRADE.NO
WHERE GRADE.SCORE > 90;
--如果能用子查询一般用子查询取代连接查询,子查询可读性更强效率更高

03EXISTS子查询

SELECT STU.*
FROM STU
WHERE EXISTS(SELECT 1 FROM GRADE WHERE NO = STU.NO 
                AND NAME = '计算机基础');
--EXISTS判断子查询返回值,如果为空则返回false,否则返回true
--执行流程:
--在stu中依次取出每条记录的no值,用改制去检查表grade的where条件
--如果grade表中存在no=stu.no并且name='计算机基础'的记录,
--EXISTS返回true并取此记录的no对应的stu的记录
--依次循环,一直到stu表中所有记录比较完成

SELECT STU.*
FROM STU
WHERE NOT EXISTS(SELECT 1 FROM GRADE WHERE NO = STU.NO 
                AND NAME = '计算机基础');

04EXISTS代替单行子查询

SELECT S1.*
FROM STU S1
WHERE EXISTS(SELECT 1 FROM STU S2
        WHERE S1.AGE = S2.AGE
        AND S2.NAME = '林琳');
--OR
SELECT STU.*
FROM STU
WHERE AGE = (SELECT AGE FROM STU WHERE NAME = '林琳');

05含聚合函数的相关子查询

SELECT STU.*
FROM STU
WHERE 1 = (SELECT COUNT(*) FROM GRADE WHERE NO = STU.NO);

06带IN的相关子查询

SELECT STU.*
FROM STU
WHERE '计算机基础' IN (SELECT NAME FROM GRADE WHERE NO = STU.NO);

07包含分组的相关子查询

SELECT DEPT, AVG(AGE)
FROM STU S1
GROUP BY S1.DEPT
HAVING AVG(AGE) < ANY(SELECT AGE
                        FROM STU S2
                        WHERE S1.DEPT = S2.DEPT);
--ANY表示任意个,小于任意一个即可符合条件
--分组年龄平均值小于分组内任意个年龄即符合条件         
--相关子查询中子查询的查询条件依赖与外层父查询的某个列值并依次执行
--执行效率一般低于连接查询,但子查询的性能完全依赖于查询和有关数据。    

09带ALL的子查询

SELECT STU.*
FROM STU
WHERE DEPT <>'12计算机'
AND AGE < ALL(SELECT AGE FROM STU WHERE DEPT = '12计算机');    
-- ALL表示所有值比较并都满足条件才为true;ANY 表示任意值满足即条件成立 

10嵌套子查询

SELECT STU.*
FROM STU
WHERE NO IN(SELECT NO FROM GRADE
            WHERE NAME IN (SELECT NAME FROM COURSE
                            WHERE SCORE = 4))
      AND DEPT = '12计算机'
ORDER BY AGE DESC;
--ORACLE支持的嵌套层次最多为255,应尽量多层嵌套,使用表连接查询性能可能会更高

11FROM子句后的子查询

SELECT *
FROM(SELECT * FROM STU WHERE AGE >22);
--FROM子查询经常在做临时表中使用

12SELECT子句后的子查询

SELECT STU.*,(SELECT SYSDATE FROM DUAL)
FROM STU;
--SELECT子句中使用子查询时一定要保证是单行返回值子查询才能成功执行

13HAVING子句后的子查询

SELECT DEPT ,COUNT(1)
FROM STU
GROUP BY DEPT
HAVING DEPT IN
(SELECT DEPT FROM STU WHERE AGE>22)

14子查询返回空值

SELECT STU.*
FROM STU
WHERE DEPT = (SELECT DEPT
                FROM STU
                WHERE AGE < 20)
ORDER BY NO
--子查询查询结果集为null,将导致父查寻结果集也为NULL
DROP TABLE EMP CASCADE CONSTRAINTS;
CREATE TABLE EMP
(
  EMPNO     NUMBER(4),
  ENAME     VARCHAR2(10 BYTE),
  JOB       VARCHAR2(9 BYTE),
  MGR       NUMBER(4),
  HIREDATE  DATE,
  SAL       NUMBER(7,2),
  COMM      NUMBER(7,2),
  DEPTNO    NUMBER(2)
);
Insert into EMP
   (EMPNO, ENAME, JOB, MGR, HIREDATE,
    SAL, DEPTNO)
 Values
   (7369, 'SMITH', 'CLERK', 7902, TO_DATE('1980/12/17', 'YYYY/MM/DD'),
    800, 20);
Insert into EMP
   (EMPNO, ENAME, JOB, MGR, HIREDATE,
    SAL, COMM, DEPTNO)
 Values
   (7499, 'ALLEN', 'SALESMAN', 7698, TO_DATE('1981/2/20', 'YYYY/MM/DD'),
    1600, 300, 30);
Insert into EMP
   (EMPNO, ENAME, JOB, MGR, HIREDATE,
    SAL, COMM, DEPTNO)
 Values
   (7521, 'WARD', 'SALESMAN', 7698, TO_DATE('1981/2/22', 'YYYY/MM/DD'),
    1250, 500, 30);
Insert into EMP
   (EMPNO, ENAME, JOB, MGR, HIREDATE,
    SAL, DEPTNO)
 Values
   (7566, 'JONES', 'MANAGER', 7839, TO_DATE('1981/4/2', 'YYYY/MM/DD'),
    2975, 20);
Insert into EMP
   (EMPNO, ENAME, JOB, MGR, HIREDATE,
    SAL, COMM, DEPTNO)
 Values
   (7654, 'MARTIN', 'SALESMAN', 7698, TO_DATE('1981/9/28', 'YYYY/MM/DD'),
    1250, 1400, 30);
Insert into EMP
   (EMPNO, ENAME, JOB, MGR, HIREDATE,
    SAL, DEPTNO)
 Values
   (7698, 'BLAKE', 'MANAGER', 7839, TO_DATE('1981/5/1', 'YYYY/MM/DD'),
    2850, 30);
Insert into EMP
   (EMPNO, ENAME, JOB, MGR, HIREDATE,
    SAL, DEPTNO)
 Values
   (7782, 'CLARK', 'MANAGER', 7839, TO_DATE('1981/6/9', 'YYYY/MM/DD'),
    2450, 10);
Insert into EMP
   (EMPNO, ENAME, JOB, MGR, HIREDATE,
    SAL, DEPTNO)
 Values
   (7788, 'SCOTT', 'ANALYST', 7566, TO_DATE('1982/12/9', 'YYYY/MM/DD'),
    3000, 20);
Insert into EMP
   (EMPNO, ENAME, JOB, HIREDATE, SAL,
    DEPTNO)
 Values
   (7839, 'KING', 'PRESIDENT', TO_DATE('1981/11/17', 'YYYY/MM/DD'), 5000,
    10);
Insert into EMP
   (EMPNO, ENAME, JOB, MGR, HIREDATE,
    SAL, COMM, DEPTNO)
 Values
   (7844, 'TURNER', 'SALESMAN', 7698, TO_DATE('1981/9/8', 'YYYY/MM/DD'),
    1500, 0, 30);
Insert into EMP
   (EMPNO, ENAME, JOB, MGR, HIREDATE,
    SAL, DEPTNO)
 Values
   (7876, 'ADAMS', 'CLERK', 7788, TO_DATE('1983/1/12', 'YYYY/MM/DD'),
    1100, 20);
Insert into EMP
   (EMPNO, ENAME, JOB, MGR, HIREDATE,
    SAL, DEPTNO)
 Values
   (7900, 'JAMES', 'CLERK', 7698, TO_DATE('1981/12/3', 'YYYY/MM/DD'),
    950, 30);
Insert into EMP
   (EMPNO, ENAME, JOB, MGR, HIREDATE,
    SAL, DEPTNO)
 Values
   (7902, 'FORO', 'ANALYST', 7566, TO_DATE('1981/12/3', 'YYYY/MM/DD'),
    3000, 20);
Insert into EMP
   (EMPNO, ENAME, JOB, MGR, HIREDATE,
    SAL, DEPTNO)
 Values
   (7934, 'MILLER', 'CLERK', 7782, TO_DATE('1982/1/23', 'YYYY/MM/DD'),
    1300, 10);
COMMIT;
 
DROP TABLE GRADE CASCADE CONSTRAINTS;
CREATE TABLE GRADE
(
  NO     VARCHAR2(10 BYTE)                      NOT NULL,
  NAME   VARCHAR2(10 BYTE),
  SCORE  NUMBER
);
Insert into GRADE
   (NO, NAME, SCORE)
 Values
   ('120001', '计算机基础', 85);
Insert into GRADE
   (NO, NAME, SCORE)
 Values
   ('120003', '计算机基础', 96);
Insert into GRADE
   (NO, NAME, SCORE)
 Values
   ('120004', '计算机基础', 60);
COMMIT;
 
DROP TABLE COURSE CASCADE CONSTRAINTS;
CREATE TABLE COURSE(
NAME VARCHAR2(20),
SCORE NUMBER
);
INSERT INTO COURSE VALUES('计算机基础', 4);
INSERT INTO COURSE VALUES('数据结构', 4);
INSERT INTO COURSE VALUES('计算机英语', 2);
COMMIT;
 
DROP TABLE GROUP_BY_TEST CASCADE CONSTRAINTS;
CREATE TABLE GROUP_BY_TEST
(
  NAME    VARCHAR2(20 BYTE),
  CLASS   VARCHAR2(20 BYTE),
  ITEM    VARCHAR2(20 BYTE),
  OBJECT  VARCHAR2(20 BYTE),
  PRICE   NUMBER
);
Insert into GROUP_BY_TEST
   (NAME, CLASS, ITEM, OBJECT, PRICE)
 Values
   ('springy', '3C', 'phone', 'huawei', 4000);
Insert into GROUP_BY_TEST
   (NAME, CLASS, ITEM, OBJECT, PRICE)
 Values
   ('springy', '3C', 'phone', 'xiaomi', 3000);
Insert into GROUP_BY_TEST
   (NAME, CLASS, ITEM, OBJECT, PRICE)
 Values
   ('springy', '3C', 'computer', 'mac', 10000);
Insert into GROUP_BY_TEST
   (NAME, CLASS, ITEM, OBJECT, PRICE)
 Values
   ('springy', '3C', 'phone', 'thinkpad', 8000);
Insert into GROUP_BY_TEST
   (NAME, CLASS, ITEM, OBJECT, PRICE)
 Values
   ('springy', '3C', 'phone', 'huawei', 4000);
Insert into GROUP_BY_TEST
   (NAME, CLASS, ITEM, OBJECT, PRICE)
 Values
   ('springy', 'clothes', 'shoes', 'adidas', 300);
Insert into GROUP_BY_TEST
   (NAME, CLASS, ITEM, OBJECT, PRICE)
 Values
   ('springy', 'clothes', 'shoes', 'lining', 400);
Insert into GROUP_BY_TEST
   (NAME, CLASS, ITEM, OBJECT, PRICE)
 Values
   ('springy', 'clothes', 'pants', 'jackjones', 500);
Insert into GROUP_BY_TEST
   (NAME, CLASS, ITEM, OBJECT, PRICE)
 Values
   ('stephenson', 'clothes', 'shoes', 'adivon', 200);
Insert into GROUP_BY_TEST
   (NAME, CLASS, ITEM, OBJECT, PRICE)
 Values
   ('stephenson', 'clothes', 'shoes', 'nike', 300);
Insert into GROUP_BY_TEST
   (NAME, CLASS, ITEM, OBJECT, PRICE)
 Values
   ('stephenson', 'clothes', 'skirt', 'nike', 300);
Insert into GROUP_BY_TEST
   (NAME, CLASS, ITEM, OBJECT, PRICE)
 Values
   ('stephenson', 'clothes', 'skirt', 'adidas', 400);
COMMIT;

猜你喜欢

转载自www.cnblogs.com/weick/p/12778479.html