GROUP BY 子句总是跟在 WHERE 子句后面,当 WHERE 子句缺省时,它跟在 FROM 子句后面。
HAVING 子句常用于在计算出聚集之后对行的查询进行控制。) SELECT CNO, AVG(GRADE), STUDENTS = COUNT(*) FROM ENROLLS GROUP BY CNO
HAVING COUNT(*) >= 3
相关子查询
例 37 查询没有选任何课程的学生的学号和姓名。(当一个子查询涉及到一个来自外部查询的列时,称为相关子查询( Correlated Subquery) 。相关子查询要用到存在测试谓词 EXISTS 和 NOT EXISTS ,以及 ALL 、 ANY ( SOME )等。) SELECT SNO, SNAME FROM STUDENTS WHERE NOT EXISTS
(SELECT *
FROM ENROLLS
WHERE ENROLLS.SNO=STUDENTS.SNO) 例 38 查询哪些课程只有男生选读。 SELECT DISTINCT CNAME
FROM COURSES C WHERE ' 男 ' = ALL (SELECT SEX
FROM ENROLLS , STUDENTS
WHERE ENROLLS.SNO=STUDENTS.SNO AND ENROLLS.CNO=C.CNO)
例 39 要求给出一张学生、籍贯列表,该表中的学生的籍贯省份,也是其他一些学生的籍贯省份。
SELECT SNAME, BPLACE FROM STUDENTS A WHERE EXISTS
(SELECT *
FROM STUDENTS B
WHERE A.BPLACE=B.BPLACE AND A.SNO < > B.SNO)
例 40 找出选修了全部课程的学生的姓名。
本查询可以改为:查询这样一些学生,没有一门课程是他不选修的。 SELECT SNAME FROM STUDENTS WHERE NOT EXISTS
(SELECT *
FROM COURSES
WHERE NOT EXISTS (SELECT *
FROM ENROLLS
WHERE ENROLLS.SNO = STUDENTS.SNO AND ENROLLS.CNO = COURSES.CNO)) 关系代数运算
例 41 设有某商场工作人员的两张表:营业员表 SP_SUBORD 和营销经理表 SP_MGR ,其关系数据模式如下:
SP_SUBORD (SALPERS_ID, SALPERS_NAME, MANAGER_ID, OFFICE) SP_MGR (SALPERS_ID, SALPERS_NAME, MANAGER_ID, OFFICE)
其中,属性 SALPERS_ID 为工作人员的编号 , SALPERS_NAME 为工作人员的姓名 , MANAGER_ID 为所在部门经理的编号 , OFFICE 为工作地点。 若查询全部商场工作人员,可以用下面的 SQL 语句: (SELECT * FROM SP_SUBORD) UNION
(SELECT * FROM SP_MGR) 或等价地用下面的 SQL 语句: SELECT *
FROM (TABLE SP_SUBORD UNION TABLE SP_MGR) ( 2 ) INTERSECT
(SELECT * FROM SP_SUBORD) INTERSECT
(SELECT * FROM SP_MGR) 或等价地用下面的 SQL 语句:
SELECT *
FROM (TABLE SP_SUBORD INTERSECT TABLE SP_MGR) 或用带 ALL 的 SQL 语句: (SELECT * FROM SP_SUBORD) INTERSECT ALL
(SELECT * FROM SP_MGR) 或
SELECT *
FROM (TABLE SP_SUBORD INTERSECT ALL TABLE SP_MGR) ( 3 ) EXCEPT
(SELECT * FROM SP_MGR) EXCEPT
(SELECT * FROM SP_SUBORD) 或等价地用下面的 SQL 语句:
SELECT *
FROM (TABLE SP_MGR EXCEPT TABLE SP_ SUBORD) 或用带 ALL 的 SQL 语句:
(SELECT * FROM SP_MGR)
EXCEPT ALL
(SELECT * FROM SP_SUBORD)
例 42 查询籍贯为四川、课程成绩在 80 分以上的学生信息及其成绩。(自然连接) (SELECT * FROM STUDENTS WHERE BPLACE=? 四川 ?) NATURAL JOIN
(SELECT * FROM ENROLLS WHERE GRADE >=80)
例3.43 列出全部教师的姓名及其任课的课程号、班级。
(外连接与外部并外连接允许在结果表中保留非匹配元组,空缺部分填以 NULL 。外连接的作用是在做连接操作时避免丢失信息。
外连接有 3 类:
( 1 )左外连接( Left Outer Join )。连接运算谓词为 LEFT [OUTER] JOIN ,其结果表中保留左关系的所有元组。
( 2 )右外连接( Right Outer Join )。连接运算谓词为 RIGHT [OUTER] JOIN ,其结果表中保留右关系的所有元组。
( 3 )全外连接( Full Outer Join )。连接运算谓词为 FULL [OUTER] JOIN ,其结果表中保留左右两关系的所有元组。)
SELECT TNAME, CNO, CLASS
FROM TEACHERS LEFT OUTER JOIN TEACHING USING (TNO)
SQL 的数据操纵
例 44 把教师李映雪的记录加入到教师表 TEACHERS 中。(插入) INSERT INTO TEACHERS
VALUES(1476 , ' 李映雪 ' , 44 , ' 副教授 ') 例 45 成绩优秀的学生将留下当教师。
INSERT INTO TEACHERS (TNO , TNAME) SELECT DISTINCT SNO , SNAME
FROM STUDENTS , ENROLLS
WHERE STUDENTS.SNO = ENROLLS.SNO AND GRADE >= 90 例 47 把所有学生的年龄增加一岁。(修改) UPDATE STUDENTS
SET AGE = AGE+1
例 48 学生张春明在数据库课考试中作弊,该课成绩应作零分计。 UPDATE ENROLLS SET GRADE = 0
WHERE CNO = 'C1' AND ' 张春明 ' =
(SELECT SNAME
FROM STUDENTS
WHERE STUDENTS.SNO=ENROLLS.SNO)
例 49 从教师表中删除年龄已到 60 岁的退休教师的数据。(删除)
DELETE FROM TEACHERS WHERE AGE >= 60
SQL 的数据控制
例 50 授予 LILI 有对表 STUDENTS 的查询权。(表/视图特权的授予
一个 SQL 特权允许一个被授权者在给定的数据库对象上进行特定的操作。授权操作的数据库对象包括:表 / 视图、列、域等。授权的操作包括: INSERT 、 UPDATE 、 DELETE 、 SELECT 、 REFERENCES 、 TRIGGER 、 UNDER 、 USAGE 、 EXECUTE 等。其中 INSERT 、 UPDATE 、 DELETE 、 SELECT 、 REFERENCES 、 TRIGGER 有对表做相应操作的权限,故称为表特权。) GRANT SELECT ON STUDENTS TO LILI
WITH GRANT OPTION
例 51 取消 LILI 的存取 STUDENTS 表的特权。 REVOKE ALL ON STUDENTS
FROM LILI CASCADE
不断补充中: 1. 模糊查找:
它判断列值是否与指定的字符串格式相匹配。可用于char、varchar、text、ntext、datetime和smalldatetime等类型查询。
可使用以下通配字符:
百分号%:可匹配任意类型和长度的字符,如果是中文,请使用两个百分号即%%。 下划线_:匹配单个任意字符,它常用来限制表达式的字符长度。
方括号[]:指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。[^]:其取值也[] 相同,但它要求所匹配对象为指定字符以外的任一个字符。 例如:
限制以Publishing结尾,使用LIKE '%Publishing' 限制以A开头:LIKE '[A]%' 限制以A开头外:LIKE '[^A]%'
2.更改表格
ALTER TABLE table_name
ADD COLUMN column_name DATATYPE
说明:增加一个栏位(没有删除某个栏位的语法。) ALTER TABLE table_name
ADD PRIMARY KEY (column_name) 说明:更改表得的定义把某个栏位设为主键。 ALTER TABLE table_name
DROP PRIMARY KEY (column_name)
说明:把主键的定义删除。 3.group by
在select 语句中可以使用group by 子句将行划分成较小的组,然后,使用聚组函数返回每一个组的汇总信息,另外,可以使用having子句限制返回的结果集。group by 子句可以将查询结果分组,并返回行的汇总信息Oracle 按照group by 子句中指定的表达式的值分组查询结果。
在带有group by 子句的查询语句中,在select 列表中指定的列要么是group by 子句中指定的列,要么包含聚组函数
select max(sal),job emp group by job;
(注意max(sal),job的job并非一定要出现,但有意义)
查询语句的select 和group by ,having 子句是聚组函数唯一出现的地方,在where 子句中不能使用聚组函数。
select deptno,sum(sal) from emp where sal>1200 group by deptno having sum(sal)>8500 order by deptno;
当在gropu by 子句中使用having 子句时,查询结果中只返回满足having条件的组。在一个sql语句中可以有where子句和having子句。having 与where 子句类似,均用于设置限定条件
where 子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,条件中不能包含聚组函数,使用where条件显示特定的行。
having 子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having 条件显示特定的组,也可以使用多个分组标准进行分组。 查询每个部门的每种职位的雇员数
select deptno,job,count(*) from emp group by deptno,job;
4.外连接与内连接
有时候,即使在连接的表中没有相应的行,用户可能想从一张表中看数据,Oracle提供了外连接实现该功能。
内连接是指连接查询只显示完全满足连接条件的记录,即等值连接,外连接的查询结果是内连接查询结果的扩展。外连接不仅返回满足连接条件的所有记录而且也返回了一个表中那些在另一个表中没有匹配行的记录。外连接的操作符是“+”。“+”号放在连接条件中信息不完全的那一边(即没有相应行的那一边)。运算符“+”影响NULL行的建立。建一行或多行NULL来匹配连接的表中信息完全的行。
外连接运算符“+”只能出现在where子句中表达式的一边。
假如在多张表之间有多个连接条件,外连接运算符不能使用or,in逻辑运算符与其它条件组合。
假如emp表中deptno=10的ename为空值,dept表中deptno=20的loc为空值: 1.
select
ename,dept.deptno,loc from
emp,dept