Oracle基础操作入门

select语句

--选择全部列
select * from departments;
--选择特定列
select department_id,department_name from departments;
复制代码

算数运算符(+ - * /)

--使用数学运算符,规则如下:
--乘除的优先级高于加减
--同一优先级运算符从左向右执行
--括号内的运算先执行
select last_name,salary,salary+300 from employees;
select last_name,salary,salary*12+100 from employees;
select last_name,salary,(salary+100)*12 from employees;
复制代码

定义空值

--空值是无效的,未指定的,未知的或不可预知的值
--空值不是空格或者0
select last_name,job_id,salary,commission_pct from employees;
--空值在数学运算中的使用
--包含空值的数字表达式的值都为空值
--select last_name,job_id,salary*12*commission_pct from employees;
复制代码

列的别名

--重命名一个列,紧跟列名,也可以在列名和别名之间加入关键字'AS'
--别名使用双引号,以便在别名中包含空格或特殊的字符并区分大小写
select last_name as name,commission_pct comm from employees;
select last_name as "name",commission_pct "comm" from employees;
复制代码

连接符

--把列与列,列与字符串连接在一起
--用 || 表示,可以用来合成列
select last_name||job_id as "Employees" from employees;
复制代码

字符串

--字符串可以是SELECT列表中的一个字符,数字,日期
--日期和字符只能在单引号中出现
select last_name || ' is a ' || job_id as "Employees Details" from employees;
复制代码

重复行

--在SELECT子句中使用关键字"DISTINCT"删除重复行。
select department_id from employees;
select distinct department_id from employees;
复制代码

过滤

--使用where子句,将不满足天剑的行过滤掉
--where子句紧随from子句
SELECT
	employee_id,
	last_name,
	job_id,
	department_id
FROM
	employees
WHERE
	department_id = 90;
复制代码

字符和日期

--字符和日期要包含在单引号中
--字符大小写敏感,日期格式敏感
--默认的日期格式为DD-MON月-RR  (PL/SQL)
SELECT
	last_name,
	hire_date,
	department_id
FROM
	employees
WHERE
	hire_date = '7-6月-1994';
复制代码

比较运算

--常见比较运算符 = > >= < <= <>(!=)
SELECT
	last_name,
	salary
FROM
	employees
WHERE
	salary <= 3000;
	
--其它比较运算
--between...and...  在两个值之间(包含边界)
SELECT
	last_name,
	salary
FROM
	employees
WHERE
	salary BETWEEN 2500
AND 3500;

--in  等于值列表中的一个
SELECT
	employee_id,
	last_name,
	manager_id
FROM
	employees
WHERE
	manager_id IN (100, 101, 201);
	
--like  模糊查询
--%代表零个或多个字符(任意个字符)
--_代表一个字符
SELECT
	first_name
FROM
	employees
WHERE
	first_name LIKE 'S%';

SELECT
	last_name
FROM
	employees
WHERE
	last_name LIKE '_o%';
	
--is null  空值
--is (not) null判断空值
SELECT
	last_name,
	manager_id
FROM
	employees
WHERE
	manager_id IS NULL;
复制代码

escape回避特殊符号

--将[%]转为[\%]、[_]转为[\_],然后再加上[ESCAPE '\'] 即可。
SELECT
	job_id
FROM
	jobs
WHERE
	job_id LIKE 'IT\_%' ESCAPE '\' ;
复制代码

逻辑运算

--and  逻辑并,要求并的关系为真
SELECT
	employee_id,
	last_name,
	job_id,
	salary
FROM
	employees
WHERE
	salary >= 10000
AND job_id LIKE '%MAN%';

--or  逻辑或
SELECT
	employee_id,
	last_name,
	job_id,
	salary
FROM
	employees
WHERE
	salary >= 10000
OR job_id LIKE '%MAN%';

--not  逻辑否
SELECT
	last_name,
	job_id
FROM
	employees
WHERE
	job_id NOT IN (
		'IT_PROG',
		'ST_CLERK',
		'SA_REP'
	);
复制代码

order by子句

--使用order by子句排序
--ASC:升序  DESC:降序
--order by子句在select语句的结尾
SELECT
	last_name,
	job_id,
	department_id,
	hire_date
FROM
	employees
ORDER BY
	hire_date DESC;
--按别名排序
SELECT
	employee_id,
	last_name,
	salary * 12 annsal
FROM
	employees
ORDER BY
	annsal;
--多个列排序	
SELECT
	last_name,
	department_id,
	salary
FROM
	employees
ORDER BY
	department_id,
	salary DESC;
复制代码

单行函数

字符函数

--大小写控制函数
--lower('SQL Course')------result:sql course
--upper('SQL Course')------result:SQL COURSE
--initcap('SQL Course')------result:Sql Course
SELECT
	employee_id,
	last_name,
	department_id
FROM
	employees
WHERE
	LOWER (last_name) = 'higgins';

--字符控制函数
--concat('Hello','World')------result:HelloWorld
--substr('HelloWorld',1,5)------result:Hello
--  substr下标从1开始,截取5个字符
--length('HelloWorld')------result:10
--instr('HelloWorld','W')------result:6
  从左到右查找字符第一次出现的位置,下标从0开始
--lpad(salary,10,*)------result:*****24000
--rpad(salary,10,*)------result:24000*****
--trim('H' from 'HelloWorld')------result:elloWorld
--  去除'HelloWorld'两边出现的'H'字符
--replace('abcd','b','m')------amcd
--  把abcd中所有的b都替换成m
SELECT
	employee_id,
	CONCAT (first_name, last_name) NAME,
	job_id,
	LENGTH (last_name),
	INSTR (last_name, 'a')
FROM
	employees
WHERE
	SUBSTR (job_id, 4) = 'REP';
复制代码

数值函数

--round(45.9262,2):四舍五入 45.93
--trunc(45.9262,2):截断 45.92
--mod(1600,300):求余 100
SELECT
	last_name,
	salary,
	MOD (salary, 5000)
FROM
	employees
WHERE
	job_id = 'SA_REP';
复制代码

日期函数

--oracle中的日期型数据实际含有两个值:日期和时间
--日期的数学运算
SELECT
	last_name,
	(SYSDATE - hire_date) / 7 AS weeks
FROM
	employees
WHERE
	department_id = 90;

--日期函数
--months_between------两个日期相差的月数
SELECT
	MONTHS_BETWEEN (
		'6-7月-1995',
		'11-11月-1994'
	)
FROM
	dual;
--add_months------向指定日期中加上若干月数
SELECT
	ADD_MONTHS ('6-7月-1995', 6)
FROM
	dual;
--next_day------指定日期的下一个星期*对应的日期
--星期日一二三四五六所代表的数字为1234567
SELECT
	NEXT_DAY ('26-10月-2018', 7)
FROM
	dual;
--last_day------本月的最后一天
SELECT
	LAST_DAY ('26-10月-2018')
FROM
	dual;
--round------日期的四舍五入
round(sysdate,'month')------2018-11-01
round(sysdate,'year')------2019-01-01
--trunc------日期截断
trunc(sysdate,'month')------2018-10-01
trunc(sysdate,'year')------2018-01-01
复制代码

转换函数

--隐式数据类型转换(oracle自动完成转换)
> varchar2--->number
> varchar2--->date
> number--->varchar2
> date--->varchar2
--显式数据类型转换
--to_char函数对日期的转换(to_char(date,format_model))
SELECT
	TO_CHAR (
		SYSDATE,
		'yyyy-mm-dd hh24:mi:ss'
	)
FROM
	dual;
--to_date函数对字符的转换(to_date(char,format_model))
--格式必须匹配
SELECT
	TO_DATE (
		'2018年10月26日08:10:21',
		'yyyy"年"mm"月"dd"日"hh24:mi:ss'
	)
FROM
	dual;
--to_char函数对数字的转换(to_char(number,format_model))
--很少会用到
--to_number函数对字符的转换(to_number(char,format_model))
--很少会用到
复制代码

通用函数

--适用于任何数据类型,同时也是用于空值
--nvl(expr1,expr2):将空值转换成一个已知的值
--可以使用的数据类型有日期、字符、数字
SELECT
	last_name,
	salary,
	NVL (commission_pct, 0),
	(salary * 12) + (
		salary * 12 * NVL (commission_pct, 0)
	) an_sal
FROM
	employees;
	
--nvl2(expr1,expr2,expr3)
--若expr1不为null,返回expr2,否则返回expr3
SELECT
	last_name,
	salary,
	commission_pct,
	NVL2 (
		commission_pct,
		'sal+comm',
		'sal'
	) income
FROM
	employees
WHERE
	department_id IN (50, 80);
	
--nullif(expr1,expr2)
--相等返回null,不等返回expr1
SELECT
	first_name,
	LENGTH (first_name) "expr1",
	last_name,
	LENGTH (last_name) "expr2",
	NULLIF (
		LENGTH (first_name),
		LENGTH (last_name)
	) result
FROM
	employees;
	
--coalesce(expr1,expr2,...,exprn)
--coalesce与nvl相比的优点在于coalesce可以同时处理交替的多个值
--如果第一个表达式为空则返回下一个表达式,对其他的参数进行coalesce
SELECT
	last_name,
	COALESCE (commission_pct, salary, 10) comm
FROM
	employees
ORDER BY
	commission_pct;
复制代码

条件表达式

--类似于sql语句中的if-then-else逻辑
--case表达式
SELECT
	last_name,
	job_id,
	salary,
	CASE job_id
WHEN 'IT_PROG' THEN
	1.10 * salary
WHEN 'ST_CLERK' THEN
	1.15 * salary
WHEN 'SA_REP' THEN
	1.20 * salary
ELSE
	salary
END "revised_salary"
FROM
	employees;
--decode函数
SELECT
	last_name,
	job_id,
	salary,
	DECODE (
		job_id,
		'IT_PROG',
		1.10 * salary,
		'ST_CLERK',
		1.15 * salary,
		'SA_REP',
		1.20 * salary,
		salary
	) "revised_salary"
FROM
	employees;
复制代码

嵌套函数

单行函数可以嵌套
嵌套函数的执行顺序是由内到外
SELECT
	last_name,
	NVL (
		TO_CHAR (manager_id),
		'No Manager'
	)
FROM
	employees
WHERE
	manager_id IS NULL;
复制代码

多表查询

  • 在where子句中写入连接条件
  • 在表中有相同列时,在列名之前加上表名前缀

等值连接

--连接n个表,至少需要n-1个连接条件
SELECT
	E .employee_id,
	E .last_name,
	E .department_id,
	D .department_id,
	D .location_id
FROM
	employees E,
	departments D
WHERE
	E .department_id = D .department_id;
复制代码

非等值连接

SELECT
	E .last_name,
	E .salary,
	j.grade_level
FROM
	employees E,
	job_grades j
WHERE
	E .salary BETWEEN j.lowest_sal
AND j.highest_sal;
复制代码

外连接

--连接条件中没有匹配行的表的列后面要加外连接运算符(+)
--左外连接:除了返回满足条件的数据外,还返回左表中不满足条件的数据
SELECT
	E .last_name,
	E .department_id,
	D .department_name
FROM
	employees E,
	departments D
WHERE
	E .department_id = D .department_id (+);
--右外连接:除了返回满足条件的数据外,还返回右表中不满足条件的数据
SELECT
	E .last_name,
	E .department_id,
	D .department_name
FROM
	employees E,
	departments D
WHERE
	E .department_id (+) = D .department_id;
复制代码

自连接

--自连接
SELECT
	M .*
FROM
	employees E,
	employees M
WHERE
	M .employee_id = E .manager_id
AND LOWER (E .last_name) = 'chen';
--子查询
SELECT
	*
FROM
	EMPLOYEES
WHERE
	EMPLOYEE_ID = (
		SELECT
			MANAGER_ID
		FROM
			EMPLOYEES
		WHERE
			LOWER (LAST_NAME) = 'chen'
	)
复制代码

使用on子句创建连接(常用)

--内连接
SELECT
	E .employee_id,
	E .last_name,
	E .department_id,
	D .department_id,
	D .location_id
FROM
	employees E
INNER JOIN departments D ON E .department_id = D .department_id;

SELECT
	E .employee_id,
	l.city,
	D .department_name
FROM
	employees E
INNER JOIN departments D ON E .department_id = D .department_id
INNER JOIN locations l ON D .location_id = l.location_id;

--左外连接
SELECT
	E .last_name,
	E .employee_id,
	D .department_name
FROM
	employees E
LEFT OUTER JOIN departments D ON E .department_id = D .department_id;

--右外连接
SELECT
	E .last_name,
	E .employee_id,
	D .department_name
FROM
	employees E
RIGHT OUTER JOIN departments D ON E .department_id = D .department_id;

--满外连接
SELECT
	E .last_name,
	D .department_id,
	D .department_name
FROM
	employees E
FULL OUTER JOIN departments D ON E .department_id = D .department_id;
复制代码

分组函数

--分组函数作用于一组数据,并对一组数据返回一个值
--avg(平均值)和sum(合计)函数
--可以对数值型数据使用avg和sum函数
SELECT
	AVG (salary),
	SUM (salary)
FROM
	employees
WHERE
	job_id LIKE '%REP%';
	
--min(最小值)和max(最大值)函数
--可以对任意数据类型的数据使用min和max函数
SELECT
	MIN (hire_date),
	MAX (hire_date)
FROM
	employees;
--count(计数)函数
--count(*)返回表中记录总数,适用于任意数据类型
SELECT
	COUNT (*)
FROM
	employees
WHERE
	department_id = 50;
--count(expr)返回expr不为空的记录总数
SELECT
	COUNT (COMMISSION_PCT)
FROM
	employees;
复制代码

组函数忽略空值

SELECT
	AVG (COMMISSION_PCT),
	COUNT (commission_pct),
	SUM (commission_pct),
	SUM (commission_pct) / COUNT (*),
	SUM (commission_pct) / COUNT (commission_pct)
FROM
	employees;
复制代码

在组函数中使用nvl函数

--nvl函数使分组函数无法忽略空值
SELECT
	AVG (NVL(commission_pct, 0))
FROM
	employees;
复制代码

distinct关键字

--count(distinct expr)返回expr非空且不重复的记录总数
SELECT
	COUNT (DISTINCT department_id)
FROM
	employees;
复制代码

group by子句语法

--可以使用group by子句将表中的数据分成若干组
--在select列表中所有未包含在组函数中的列都应该包含在group by子句中
SELECT
	department_id,
	AVG (salary)
FROM
	employees
GROUP BY
	department_id;
	
--包含在group by子句中的列不必包含在select列表中
SELECT
	AVG (salary)
FROM
	employees
GROUP BY
	department_id;
	
--在group by子句中包含多个列
SELECT
	department_id dept_id,
	job_id,
	SUM (salary)
FROM
	employees
GROUP BY
	department_id,
	job_id;
--不能在where子句中使用组函数
--可以在having子句中使用组函数
复制代码

过滤分组:having子句

--使用having过滤分组:
--行已经被分组
--使用了组函数
--满足having子句中条件的分组将被显示
SELECT
	department_id,
	MAX (salary)
FROM
	employees
GROUP BY
	department_id
HAVING
	MAX (salary) > 10000;
复制代码

嵌套组函数

--显示各部门平均工资的最大值
SELECT
	MAX (AVG(salary))
FROM
	employees
GROUP BY
	department_id;
复制代码

子查询

--子查询(内查询)在主查询之前一次执行完成
--子查询的结果被主查询(外查询)使用
SELECT
	last_name
FROM
	employees
WHERE
	salary > (
		SELECT
			salary
		FROM
			employees
		WHERE
			last_name = 'Abel'
	);

--单行子查询:只返回一行
--操作符:=  >  >=  <  <=  <>
--返回job_id与141号员工相同,salary比143号员工多的员工
--  姓名,job_id 和工资
SELECT
	last_name,
	job_id,
	salary
FROM
	employees
WHERE
	job_id = (
		SELECT
			job_id
		FROM
			employees
		WHERE
			employee_id = 141
	)
AND salary > (
	SELECT
		salary
	FROM
		employees
	WHERE
		employee_id = 143
);

--返回公司工资最少的员工的last_name,job_id和salary
SELECT
	last_name,
	job_id,
	salary
FROM
	employees
WHERE
	salary = (
		SELECT
			MIN (salary)
		FROM
			employees
	);
	
--查询最低工资大于50号部门最低工资的部门id和其最低工资
SELECT
	department_id,
	MIN (salary)
FROM
	employees
GROUP BY
	department_id
HAVING
	MIN (salary) > (
		SELECT
			MIN (salary)
		FROM
			employees
		WHERE
			department_id = 50
	);
	
--多行子查询:返回多行
--操作符:in  any  all
--in:等于列表中的任意一个
--any:和子查询返回的某一个值比较
--返回其它部门中比job_id为'IT_PROG'部门任一工资低的员工的员
--  工号、姓名、job_id 以及salary
SELECT
	employee_id,
	last_name,
	job_id,
	salary
FROM
	employees
WHERE
	salary < ANY (
		SELECT
			salary
		FROM
			employees
		WHERE
			job_id = 'IT_PROG'
	)
AND job_id <> 'IT_PROG';
--all:和子查询返回的所有值比较
--返回其它部门中比job_id为‘IT_PROG’部门所有工资都低的员工
--  的员工号、姓名、job_id 以及salary

SELECT
	employee_id,
	last_name,
	job_id,
	salary
FROM
	employees
WHERE
	salary < ALL (
		SELECT
			salary
		FROM
			employees
		WHERE
			job_id = 'IT_PROG'
	)
AND job_id <> 'IT_PROG';

复制代码

子查询中的空值问题

SELECT
	last_name,
	job_id
FROM
	employees
WHERE
	job_id = (
		SELECT
			job_id
		FROM
			employees
		WHERE
			last_name = 'Haas'
	);
--no rows selected
--子查询不反回任何行
复制代码
  • 1、查询每个月倒数第2天入职的员工的信息
SELECT
	last_name,
	hire_date
FROM
	employees
WHERE
	hire_date = LAST_DAY (hire_date) - 1
复制代码
  • 2、查询出 last_name 为 'Chen' 的 manager 的信息.
SELECT
	*
FROM
	EMPLOYEES
WHERE
	EMPLOYEE_ID = (
		SELECT
			MANAGER_ID
		FROM
			EMPLOYEES
		WHERE
			LOWER (LAST_NAME) = 'chen'
	)
复制代码
  • 3、查询平均工资高于 8000 的部门 id 和它的平均工资
SELECT
    department_id,
	AVG (salary)
FROM
	EMPLOYEES
GROUP BY
	DEPARTMENT_ID
HAVING
	AVG (salary) > 8000
复制代码
  • 4、查询工资最低的员工信息: last_name, salary
SELECT
	last_name,
	salary
FROM
	employees
WHERE
	SALARY = (
		SELECT
			MIN (salary)
		FROM
			EMPLOYEES
	);
复制代码
  • 5、查询平均工资最低的部门信息
SELECT
	*
FROM
	DEPARTMENTS
WHERE
	DEPARTMENT_ID = (
		SELECT
			DEPARTMENT_ID
		FROM
			EMPLOYEES
		GROUP BY
			DEPARTMENT_ID
		HAVING
			AVG (salary) = (
				SELECT
					MIN (AVG(salary))
				FROM
					EMPLOYEES
				GROUP BY
					department_id
			)
	)
复制代码
  • 6、查询平均工资最低的部门信息和该部门的平均工资
SELECT
	D .*, (
		SELECT
			AVG (salary)
		FROM
			EMPLOYEES E
		WHERE
			E .DEPARTMENT_ID = D .DEPARTMENT_ID
	)
FROM
	DEPARTMENTS D
WHERE
	D .DEPARTMENT_ID = (
		SELECT
			DEPARTMENT_ID
		FROM
			EMPLOYEES
		GROUP BY
			DEPARTMENT_ID
		HAVING
			AVG (salary) = (
				SELECT
					MIN (AVG(salary))
				FROM
					EMPLOYEES
				GROUP BY
					DEPARTMENT_ID
			)
	)

复制代码
  • 7、查询平均工资最高的 job 信息
SELECT
	*
FROM
	JOBS
WHERE
	job_id = (
		SELECT
			JOB_ID
		FROM
			EMPLOYEES
		GROUP BY
			JOB_ID
		HAVING
			AVG (SALARY) = (
				SELECT
					MAX (AVG(salary))
				FROM
					EMPLOYEES
				GROUP BY
					job_id
			)
	)
复制代码
  • 8、查询平均工资高于公司平均工资的部门有哪些?
SELECT
	department_id
FROM
	EMPLOYEES
GROUP BY
	DEPARTMENT_ID
HAVING
	AVG (salary) > (
		SELECT
			AVG (salary)
		FROM
			EMPLOYEES
	)
复制代码
  • 9、查询出公司中所有 manager 的详细信息
SELECT
	*
FROM
	EMPLOYEES
WHERE
	EMPLOYEE_ID IN (
		SELECT DISTINCT
			manager_id
		FROM
			EMPLOYEES
	);
复制代码
  • 10、各个部门中 最高工资中最低的那个部门的 最低工资是多少
SELECT
	MIN (salary)
FROM
	EMPLOYEES
WHERE
	DEPARTMENT_ID = (
		SELECT
			DEPARTMENT_ID
		FROM
			EMPLOYEES
		GROUP BY
			DEPARTMENT_ID
		HAVING
			MAX (SALARY) = (
				SELECT
					MIN (MAX(salary))
				FROM
					EMPLOYEES
				GROUP BY
					DEPARTMENT_ID
			)
	)
复制代码
  • 11、查询平均工资最高的部门的 manager 的详细信息: last_name, department_id, email, salary
SELECT
	last_name,
	DEPARTMENT_id,
	email,
	salary
FROM
	EMPLOYEES
WHERE
	EMPLOYEE_ID IN (
		SELECT
			MANAGER_ID
		FROM
			EMPLOYEES
		WHERE
			DEPARTMENT_ID = (
				SELECT
					DEPARTMENT_ID
				FROM
					EMPLOYEES
				GROUP BY
					DEPARTMENT_ID
				HAVING
					AVG (salary) = (
						SELECT
							MAX (AVG(salary))
						FROM
							EMPLOYEES
						GROUP BY
							DEPARTMENT_ID
					)
			)
	)
复制代码
  • 12、查询 1999 年来公司的人所有员工的最高工资的那个员工的信息
SELECT
	*
FROM
	EMPLOYEES
WHERE
	TO_CHAR (HIRE_DATE, 'yyyy') = '1999'
AND SALARY = (
	SELECT
		MAX (salary)
	FROM
		EMPLOYEES
	WHERE
		TO_CHAR (HIRE_DATE, 'yyyy') = '1999'
)
复制代码
  • 13、返回其它部门中比 job_id 为‘IT_PROG’部门所有工资都低的员工的 员工号、姓名、job_id 以及 salary
SELECT
	employee_id,
	last_name,
	job_id,
	salary
FROM
	employees
WHERE
	salary < ALL (
		SELECT
			salary
		FROM
			employees
		WHERE
			LOWER (JOB_ID) = 'it_prog'
	)
AND LOWER (JOB_ID) <> 'it_prog';
复制代码

转载于:https://juejin.im/post/5bd09d47e51d457a5763c25d

你可能感兴趣的:(Oracle基础操作入门)