Oracle 笔记02

发布于 2020-06-05  334 次阅读


数据查询

SELECT语句

SELECT [ALL|DISTINCT] column_name [,expression...]
FROM table1_name [,table2_name,view_name,...]
[WHERE condition]
[GROUP BY column_name1 [,column_name2,...]
[HAVING group_condition]]
[ORDER BY column_name2 [ASC|DESC] [,column_name3,...]];

基本查询

此处切换为 scott 账户,默认密码是 tiger,运行 Oracle 安装目录下的
/RDBMS/ADMIN/utlsampl.sql 文件即可创建接下来演示的表

表构成:

雇员表 emp

部门表 dept

无条件查询

SELECT * FROM emp;

查询指定列

SELECT deptno, dname FROM dept;

使用算数表达式

SELECT empno, sal*0.8 FROM emp;

使用字符常量:

SELECT empno,'Name is :',ename FROM emp;

使用函数:

-- 将 ename 列的输出字符置为大写
SELECT empno,UPPER(ename) FROM emp;

改变列标题

SELECT ename employeename,sal salary FROM emp;

使用连接字符串

SELECT '员工号:'||empno||'员工名:'||ename FROM emp;

显示所有行(可重复)

SELECT ALL deptno FROM emp;

显示所有行(不可重复)

SELECT DISTINCT deptno FROM emp;

有条件查询

查询不在10号部门的雇员的编号、姓名、工资

SELECT empno,ename,sal FROM emp
WHERE deptno != 10;

查询基本工资大于1500的雇员的编号、姓名、工资

SELECT empno,ename,sal FROM emp WHERE sal>1500;

查询部门编号在10-20间的雇员信息

SELECT * FROM emp WHERE deptno NOT BETWEEN 10 AND 20;

查询属于10和20号部门雇员的信息

-- 谓词 IN 可以属性值属于指定集合的元组
SELECT empno,ename,sal FROM emp WHERE deptno IN(10,30);

字符通配

 % 表示任意长(可为0)的字符串
 _ 表示任意单个字符

检索姓名中含有 'S' 字符的雇员

SELECT empno,ename FROM emp WHERE ename LIKE '%S%';

检索姓名第二个人字母为 'A' 的雇员

SELECT empno,ename FROM emp WHERE ename LIKE '_A%';

ESCAPE转义字符

在模式中,将转义字符置于通配符前,该通配符将被转义为普通字符

ESCAPE 'escape_character'

检索姓名包含 '_' 的雇员

SELECT * FROM emp WHERE ename LIKE '%x_%' ESCAPE 'x';

空值查询

涉及空值查询时使用 IS NULL 或 IS NOT NULL,这里的 IS 不能用 = 代替

查询奖金为空值的雇员

SELECT * FROM emp WHERE comm IS NULL;

逻辑运算

查询10号部门工资大于1500的雇员

SELECT * FROM emp WHERE deptno=10 AND sal>1500;

查询10号和20号部门工资大于1500的雇员

SELECT * FROM emp WHERE (deptno=10 OR deptno=20) AND sal>1500;

查询工资在1500到2000之间的雇员

SELECT * FROM emp WHERE sal>=1500 AND sal<=2000;

升序/降序 输出

--ASC 升序(默认)   DESC 降序

按工资递增的顺序输出雇员信息

SELECT empno,ename,sal FROM emp ORDER BY sal;

按工资递减的顺序输出雇员信息

SELECT empno,ename,sal FROM emp ORDER BY sal DESC;

多行排列规则

-- 首先按照第一个列或表达式进行排序
-- 第一个数据相同时,以第二个列或表达式进行排序,依此类推
-- 按照部门编号递增,工资递减的序列列出所有雇员
SELECT * FROM emp ORDER BY deptno, sal DESC;

使用列位置编号排序

SELECT empno,sal*12 salary FROM emp ORDER BY 2;

聚集函数

※ 除了COUNT(*)函数外,其他的统计函数都不考虑返回值或表达式为 NULL 的情况
※ 聚集函数只能出现在目标列表达式、ORDER BY子句和 HAVING 子句中
※ 聚集函数不能出现在 WHERE 子句和 GROUP BY 子句中
※ 默认对所有的返回行进行统计,包括重复的行
※ 如果要统计不重复的行信息,则可使用 DISTINCT 选项
※ 如果对查询结果进行了分组,则聚集函数的作用范围为各个组,否则聚集函数作用于整个查询结果

查询10号部门的人数、平均工资和最低工资

SELECT count(*),avg(sal),min(sal)
FROM emp
WHERE deptno = 10;

查询所有雇员的平均奖金和总奖金

SELECT avg(comm),sum(comm) FROM emp;

分组查询

查询不同部门的雇员人数和平均工资

SELECT deptno, count(*),avg(sal) FROM emp
GROUP BY deptno;

查询不同部门中不同工种的员工人数和平均工资

SELECT deptno, job,count(*),avg(sal) FROM emp
GROUP BY deptno, job;

查询部门平均工资高于2000的部门信息

-- 查询部门号、部门人数、部门平均工资
SELECT deptno,count(*),avg(sal)
FROM emp
GROUP BY deptno
HAVING avg(sal)>2000;

连接查询

交叉连接

emp 和 dept 表的交叉连接

-- 查询所有的雇员们,部门名
SELECT ename,dname FROM emp,dept;

内连接

查询10号部门雇员的编号、姓名等信息

SELECT
	empno,ename,sal,emp.deptno,dname
FROM emp,dept
WHERE emp.deptno = 10
AND emp.deptno = dept.deptno;

子查询

子查询的作用:
INSERT或CREATE TABLE语句 —— 将子查询的结果写到目标表中
UPDATE语句 —— 可以修改一个或多个记录的数据
DELETE语句 —— 删除一个或多个记录
WHERE和HAVING子句 —— 返回的一个或多个值

单行单列子查询

查询比7934号员工工资高的员工编号

SELECT empno
FROM emp
WHERE sal>(SELECT sal FROM emp WHERE empno=7934);

查询与10号部门某个员工工资相等的员工信息

SELECT empno,ename,sal
FROM emp
WHERE sal IN (SELECT sal FROM emp WHERE deptno=10);

查询比10号部门某个员工工资高的员工信息

SELECT empno,ename,sal
FROM emp
WHERE sal>ANY(SELECT sal FROM emp WHERE deptno=10);

查询比10号部门所有员工工资高的员工信息

SELECT empno,ename,sal
FROM emp
WHERE sal>ALL(SELECT sal FROM emp WHERE deptno=10);

单行多列子查询

查询与7844号员工的工资、工种都相同的员工信息

SELECT empno,ename,sal,job FROM emp
WHERE (sal,job)=(SELECT sal,job FROM emp WHERE empno = 7844);

多行多列子查询

查询与10号部门某个员工的工资和工种都相同的员工信息

SELECT empno,ename,sal,job FROM emp
WHERE (sal,job) IN
(SELECT sal,job FROM emp WHERE deptno = 10);

相关子查询

无关子查询:子查询在执行时不需要外部父查询的信息
相关子查询:
※ 子查询在执行时要引用外部父查询的信息
※ 经常使用EXISTS和NOT EXSISTS谓词来实现
※ 如果子查询返回结果,则条件为TRUE
※ 如果子查询没有返回结果,则条件为FALSE

查询没有任何员工的部门号、部门名

SELECT deptno,dname,loc
FROM dept
WHERE NOT EXISTS(
	SELECT * FROM emp WHERE emp.deptno = dept.deptno);

查询各个员工的员工号、员工名及其所在部门平均工资

-- 在FROM子句中使用子查询时,该子查询被作为视图对待,必须为该子查询指定别名
SELECT empno,ename,d.avgsal
FROM
	emp,
	(SELECT deptno,avg(sal) avgsal FROM emp
	 GROUP BY deptno)d
 WHERE emp.deptno = d.deptno;

查询各个部门号、部门名、部门人数和部门平均工资

SELECT dept.deptno,dname,d.amount,d.avgsal
FROM
	dept,
	(SELECT deptno,count(*) amount,avg(sal) avgsal
	 FROM emp GROUP BY deptno)d
WHERE dept.deptno = d.deptno;

合并查询

-- 当要合并几个查询的结果集时,这几个查询的结果集必须具有相同的列数与数据类型
-- 如果要对最终的结果集排序,只能在最后一个查询之后用ORDER BY子句指明排序类型
SELECT query_statement1
[UNION|UNION ALL|INTERSECT|MINUS]
SELECT query_statement2;

UNION

查询10号部门的员工信息以及工资大于2000的所有员工的信息

-- UNION 默认会消除重复记录
SELECT empno,ename,sal,deptno FROM emp WHERE deptno=10
UNION
SELECT empno,ename,sal,deptno FROM emp WHERE sal>2000
ORDER BY deptno;

查询10号部门的员工信息以及工资大于2000的所有员工的信息

-- 问题和上面的一样,但这里要求保留重复的记录
-- 保留需要用到 UNION ALL
SELECT empno,ename,sal,deptno FROM emp WHERE deptno=10
UNION ALL
SELECT empno,ename,sal,deptno FROM emp WHERE sal>2000
ORDER BY deptno;

INTERSECT 取交集

查询30号部门中工资大于2000的员工信息

-- INTERSECT 用于获取几个查询结果集的交集,返回结果默认按第一列进行排序
SELECT empno,ename,sal,deptno FROM emp WHERE deptno = 30
INTERSECT
SELECT empno,ename,sal,deptno FROM emp WHERE sal>2000;

MINUS 取差集

查询30号部门中工种不是“SALESMAN”的员工信息

-- MINUS 用于获取几个查询结果集的差集,返回结果默认按第一列进行排序
SELECT empno,ename,job FROM emp WHERE deptno=30
MINUS
SELECT empno,ename,job FROM emp WHERE job = 'SALESMAN'


何为BS?B-big,S-shui。