01使用GROUP BY子句实现分组
SELECT MAX(AGE) AS 最大年龄, DEPT AS 所在班级 FROM STU GROUP BY DEPT;
02按条件查询并分组
SELECT MAX(AGE) AS 最大年龄, DEPT AS 所在班级 FROM STU WHERE GENTLE = '男' GROUP BY DEPT;
03使用CUBE汇总数据
SELECT NO AS 学号, DEPT AS 所在班级, AVG(AGE) AS 平均年龄, GROUPING(NO), GROUPING(DEPT) FROM STU GROUP BY CUBE(DEPT, NO); --CUBE参数的作用除了返回GROUP BY子句指定列外,还返回按组统计的行, --返回结果先按分组的第一个条件NO列排序显示,再按第二个条件DEPT列排序显示以此类推 --GROUPING用来判断某行数据是不是按照ROLLUP或CUBE进行汇总,返回0或1, --1表示指定列由于汇总符产生NULL值,也表示汇总时忽略该列。
04使用ROLLUP汇总数据
SELECT NO AS 学号, DEPT AS 所在班级, AVG(AGE) AS 平均年龄, GROUPING(NO), GROUPING(DEPT) FROM STU GROUP BY ROLLUP(DEPT, NO) ORDER BY NO, DEPT;
05使用HAVING子句过滤分组数据
SELECT MAX(AGE) AS 最大年龄, DEPT AS 所在班级 FROM STU GROUP BY DEPT HAVING MAX(AGE) >=25;
06区别HAVING与WHERE子句
07使用ORDER BY子句排序
SELECT * FROM STU ORDER BY GENTLE ASC, AGE DESC;--ASC升序,默认可省略;DESC降序
08MINUS(补集)
返回第一个查询结果的记录减去第二个查询结果的记录;查询列要一致
09INTERSECT(交集)
10UNION ALL / UNION(并集)
11无条件多表查询
SELECT S.NO AS 学号, S.NAME AS 姓名, G.NAME AS 学科, G.SCORE AS 成绩 FROM STU S, GRADE G;
查笛卡尔积 表行数相乘
12有共有字段的表等值查询
SELECT STU.*, GRADE.* FROM STU, GRADE WHERE STU.NO =GRADE.NO; --先取STU表中的第一个NO记录值与GRADE表中的所有的NO值一一比较,将相等的选出, --再取STUdents第一个NO记录值与GRADE表中的所有的NO值一一比较,将相等的选出,以此类推, --运算符两边至少要有一个相等的记录,否则查询记录为空。
13含条件的等值查询
SELECT STU.*, GRADE.* FROM STU, GRADE WHERE STU.NO =GRADE.NO AND STU.NAME = '张清';
14有共有字段的表非等值连接
SELECT STU.*, GRADE.* FROM STU, GRADE WHERE STU.NO <> GRADE.NO; --相当与无条件连接的查询结果集减去等值查询结果集
15两个表内连接
SELECT STU.*, GRADE.* FROM STU INNER JOIN GRADE ON STU.NO = GRADE.NO; --INNER JOIN关键字是SQL标准写法,INNER可省略 --等值连接与非等值连接都属于内连接。指多个表的相关字段满足连接条件时, --则从这两个表中提取数据并组合成新的记录。
16表自连接
SELECT S1.NO AS 学号, S1.NAME AS 姓名, S1.AGE AS 年龄 FROM STU S1 INNER JOIN STU S2 ON S1.AGE = S2.AGE WHERE S1.NO <> S2.NO ORDER BY S1.AGE DESC; --查询STU表中年龄相同的结果集
17表左外连接
SELECT STU.*, GRADE.* FROM STU LEFT OUTER JOIN GRADE ON STU.NO = GRADE.NO; --OUTER可省略 --OR SELECT STU.*, GRADE.* FROM STU, GRADE WHERE STU.NO = GRADE.NO(+); --左外连接结果集包括LEFT JOIN子句中指定的左表(主表)的所有行, --如果左表的某行在右表中没有匹配行,则在相关联的结果集中右表所有选择列均为空值
18表右外连接
SELECT STU.*, GRADE.* FROM STU RIGHT OUTER JOIN GRADE ON STU.NO = GRADE.NO; --OUTER可省略 --OR SELECT STU.*, GRADE.* FROM STU, GRADE WHERE STU.NO(+) = GRADE.NO; --右表(GRADE)为主表
19表全外连接
SELECT STU.*, GRADE.* FROM STU FULL OUTER JOIN GRADE ON STU.NO = GRADE.NO; --全外连接操作产生的结果集不仅包括符合连接条件的匹配行, --而且包括两个连表中的所有记录,与左外连接和右外连接不同的是全外连接还返回左右表中不符合查询条件的数据行,以空值补全对应行的列值
20多表连接
SELECT STU.*, GRADE.*, COURSE.* FROM STU INNER JOIN GRADE ON STU.NO = GRADE.NO INNER JOIN COURSE ON GRADE.NAME = COURSE.NAME WHERE STU.NAME = '张清'; --OR SELECT STU.*, GRADE.*, COURSE.* FROM STU, GRADE, COURSE WHERE STU.NO = GRADE.NO AND GRADE.NAME = COURSE.NAME AND STU.NAME = '张清'; --太多表进行连接将极大降低性能,一般select语句连接的表最多为8~10个,否则就要考虑数据库设计可能不是最优
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;