oracle 11G 安装文档:https://download.csdn.net/download/u014749668/10639855
oracle 客户端实例配置:https://download.csdn.net/download/u014749668/10639858
1 sqlplus 基本使用
登录
sqlplus scott/11
sqlplus sys/密码 as sysdba
sqlplus / as sysdba --管理员
sqlplus 用户/密码 --本地登录
sqlplus 用户/密码@//主机号(ip)/实例名(orcl)
sqlplus scott/11@//192.168.0.29/orcl
退出
exit 、 quit
启动数据库实例
startup
关闭数据库实例
shutdown
开启远程监听服务(不是在sqlplus,而是在shell环境里边)
lsnrctl start
lsnrctl status
lsnrctl stop
显示当前用户
show user
清屏
host cls
修改用户密码
alter user scott account unlock
alter user scott identified by "新密码"
显示当前方案、用户有什么表
select * from tab
查看表结构
desc 表名
修改sqlplus行宽
set linesize 140;
修改页高
set pagesize 50
使用sqlplus启动的时候就自动设置列宽页高
写在product\11.2.0\client_1\sqlplus\admin\glogin.sql
DML 数据操作语言
增 insert
删 delete
改 update
查 select
DDL 数据定义语言
create table(创建表)
alter table(修改表)
truncate table(清空表)
drop table(删除表)
create view(视图)
create index(索引)
create sequence(序列)
create synonym(同义词)
DCL数据控制语言
commit(提交)
rollback(回滚)
2 简单查询
select *|列名 [as 别名],列名2... | 表达式
from 表名
where cond
1 查询emp表的所有数据
select * from emp;
2 查询员工号,姓名,月薪,奖金,年薪,年收入 并修改列名为中文(返回结果集)
select empno as "工号", ename "姓名", sal 月薪,
comm "奖 金", sal*12 年薪, sal*12+nvl(comm,0) 年收入
from emp
【结论】:null 做任何数值运算都为null
列的别名使用双引号,如果列名中间有空格不能省略双引号
【】使用nvl函数,将null变成0
nvl(exp,val) -- 如果exp为空 那么就返回val
3 查看员工表所有部门编号并去除重复
使用【distinct】 去重
select distinct deptno from emp
结论:distinct 去重,是去重除返回结果集重复的行
4 计算表达式3+2 =5
oracle提供了一个虚表,用来计算表达式——dual
3 单条件查询
1 查询10号部门的员工信息
select * from emp where deptno = 10
2 查询KING的信息
KING
select * from emp where ename = 'king' --查不到,大小写敏感
select * from emp where ename = 'KING'
【什么时候用单引号,什么时候用双引号】:
数据里边都用单引号,双引号一般用在数据库对象名(表名、列名、密码)
3 查询薪水不等于1250的员工信息
select * from emp where sal <> 1250
4 查询入职日期为1981年11月17日的员工信息
涉及到日期数据的判断
select * from v$nls_parameters; 查看环境变量 date_format 控制当前环境时间类型显示格式
alter session set nls_date_format = 'yyyy-mm-dd' 修改日期格式
select * from emp where hiredate = '1981-11-17'
4 多条件查询
与 && and
或 || or
非 ! not
1 查询10号部门中月薪为1300的员工
select * from emp where deptno =10 and sal = 1300
2 查询部门号是10或者20的员工信息
select * from emp where deptno =10 or deptno = 20
使用in
select * from emp where deptno in (10,20) ---集合使用小括号表示
3 查询部门不是10和20的员工信息
select * from emp where deptno <>10 and deptno <> 20
select * from emp where deptno not in (10,20)
如果有NULL
select * from emp where deptno not in (10,20,NULL)
【结论】:null做任何逻辑或者比较运算都为假
deptno != 10 && deptno != 20 && deptno != NULL --NULL影响了结果
deptno =10 || deptno = 20 || deptno = NULL --NULL 没有影响结果
4 查询工资介于1000到2000之间的员工
select * from emp where sal >= 1000 and sal <= 2000
使用between and 的方式
select * from emp where sal between 1000 and 2000
问题是,【between包不包括边界值 】——包括
5 查询1981年2月(含2月)到82年2月(不含2月)入职的员工信息
select * from emp where hiredate >= '1981-02-01' and hiredate <'1982-02-01'
换成between 换成 1982-01-31
6 查询没有奖金的员工信息
查询奖金为空
select * from emp where comm = null --不能使用比较运算
【使用is判断null】
select * from emp where comm is null
7 查询有奖金的员工信息
select * from emp where comm is not null
5 模糊查询
【模式匹配】
where like '模式字符串' escape '转义字符'
【模式字符串的格式】
% 表示0或者多个字符
_ 表示1个字符
1 查询员工首字母是S的员工信息
S%
select * from emp where ename like 'S%'
2 查询名字是四个字母的员工信息
select * from emp where ename like '____'
3 查询姓名带下划线的员工信息
select * from emp where ename like '%\_%' --反斜杠不是转义
sql里边本来就不提供默认的转义字符,要我们自己制定一个 使用【escape】来指定
select * from emp where ename like '%\_%' escape '\'
6 排序
按什么排序? —— 列
排的什么序? —— 升序、降序
select ...
from ...
where ...
order by 列,列2 asc|desc
1 员工信息按先后入职日期排序
select * from emp order by hiredate
2 员工信息按薪水从大到小排序
select * from emp order by sal desc
3 员工信息按部门号和薪水排序
select * from emp order by deptno,sal
按照顺序排序deptno,sal
4 员工信息按部门和薪水排列,降序
select * from emp order by deptno desc,sal desc
【结论】:asc|desc 作用在前面那列
5 员工信息按奖金倒序
select * from emp order by comm desc
NULL 会影响排序
select * from emp order by comm desc nulls last
6 员工信息按第2列排序
select * from emp order by 2
结论:按照返回结果集第几列来排序,而不是表的第几列
7 员工信息按别名排序
select enmno , sal "月薪" from emp order by "月薪";
可以根据别名进行排序
单行函数
(1) 字符函数
lower —— 小写
upper —— 大写
initcap —— 将字符串首每个单词字母变成大写
函数名(表达式)
concat —— 字符串拼接
concat(str1,str2) ——只支持两个参数
如果字符串过多,拼接推荐用 ||
select 'hello ' || 'world '|| '1234' || 123 from dual; --123 做了隐式转换
substr —— 取子串
substr(str , pos , len) --在str里边第pos个字符取子串,长度是len,len可以省略
pos 可以是负数,相当于从字符串后边往前面数
select substr('hello world',-3 ) from dual; --rld
instr —— 判断某个字符串在另一个字符串的哪个位置
instr (str , substr ) --如果找不到,就返回0,找到则返回向相应位置(第几个字符)
lpad,rpad —— 左填充,右填充
lpad ( str , len , char) -- 往str左边填充char字符到len长度
select lpad('hello', 10 , '#') from dual;
select lpad('hello', 3 , '#') from dual; --如果字符串长度比len长,就截取
trim —— 去除两边空格
select trim ( ' Hello world ') from dual;
select trim ( 'H' from 'Hello worldH') from dual; --去除两边的H
replace —— 字符串替换
replac(str , substr , replaceString) --从str里边找到substr,替换成 replaceString
(2) 数值函数
round —— 四舍五入
trunc —— 截取
ceil、floor —— 向上取整、向下取整
mod —— % 取模
select round(45.926) 四舍五入,
round(45.926,1) 四舍五入2,
trunc(45.926) 截取,
trunc(45.926,1) 截取2,
ceil(45.926) 向上取整,
floor(45.926) 向下取整,
mod(1000,600) 取模
from dual
四舍五入 四舍五入2 截取 截取2 向上取整 向下取整 取模
---------- ---------- ---------- ---------- ---------- ---------- ----------
46 45.9 45 45.9 46 45 400
(3) 转换函数
数字转字符串 to_char
to_char(数字)
to_char(数字,格式字符串)
将薪水转化为本地货币字符型
select to_char(sal,'L9999') from emp; -L 代表本地货币符号 ,9代表一位数
字符串转数字 to_number
select to_number('1234') from dual;
select to_number('¥950','L9999') from dual;
用什么格式转到数字类型的,就用什么格式转回去字符串
日期转字符串 to_char
hiredate 转字符串
select hiredate ,to_char(hiredate , 'dd-mm-yyyy day') from emp;
字符串转日期 to_date
select to_date( '17-12-1980 星期三' , 'dd-mm-yyyy day') from dual;
(4) 日期函数
sysdate --获取当前系统的时间
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
sysdate 不仅包含日期,还包含时间
1 显示昨天、今天、明天
日期类型的计算 +1 -1 单位是天
select sysdate -1 昨天 , sysdate 今天 , sysdate +1 明天 from dual;
2 计算员工工龄,按照日、周、月、年显示
日期相减,得到两个日期相隔多少天
select ename ,hiredate,
sysdate- hiredate "天",
(sysdate - hiredate) / 7 "周",
(sysdate - hiredate) / 30 "月",
(sysdate - hiredate) / 365 "年"
from emp
months_between
months_between(date1 , date2 ) --算出两个时间相差多少个月——精确值
select ename ,hiredate,
(sysdate - hiredate) / 30 "月",
months_between(sysdate,hiredate) "精确月"
from emp
add_months
add_months(date, n) 在date上添加n个月
计算明年今日
select add_months(sysdate,12) "明年今日" from dual;
last_day
last_day(date) --返回date 所在 月的最后一天
select last_day(sysdate) from dual;
next_day
next_day(sysdate,'星期三') -- 返回下一个星期几是哪一天
select next_day(sysdate,'星期三') from dual;
(5) 通用函数
nvl
nvl(exp,retval) 如果exp是空,就返回retval,否则返回exp
nvl2
nvl2(exp , val1 , val2) 如果exp不为空 ,返回val1, 否则返回val2
查询员工信息,有奖金就显示'有奖金',没奖金就显示'没奖金'
(6) 条件语句
case when then else end —— 标准 SQL 提供的
decode ——oracle提供的一个函数
总裁决定给大家涨工资,主管涨1000,销售涨500,其他涨200
switch(job)
{
case 'MANAGER' : sal + 1000; break;
case 'SALESMAN' : sal + 500; break;
default : sal + 200; break;
}
case(job)
when 'MANAGER' then sal + 1000
when 'SALESMAN' then sal + 500
else sal + 200
end
select ename , job , sal 涨前工资 ,
case(job)
when 'MANAGER' then sal + 1000
when 'SALESMAN' then sal + 500
else sal + 200
end "涨后工资"
from emp
使用decode
decode(exp , val1 ,val2 ,val3 , val4 ..... , defaultVal);
如果exp 是 val1 返回val2 , 否则继续判断
是val3 返回 val4 ....
如果都不是,就返回defaultVal
多行计算函数
(1)统计函数
遍历表的各行数据,统计完后再返回结果
sum
1 求员工工资总和
select sum(sal) from emp;
count
1 求员工数量,有奖金的员工数
select count(*) 员工数量, count(comm) from emp
count(*) 只要一行有数据就统计
count(comm) 只有comm 不是null才统计
结论:
【】NULL不会参与统计函数的统计
2 求工作岗位数量 统计去重
select count(distinct job) from emp;
max/min
求员工最高工资和最低工资
avg
求员工平均工资
select avg(sal) from emp;
求员工平均奖金(三种方式)
select avg(comm) ,sum(comm)/count(*) ,sum(comm)/count(comm) from emp;
分组统计
select…
from…
where…
group by 列1,列2…,根据某列,多列进行分组
having cond 分组完成在判断
order by 列1,列2…,asc | desc
select ...
from ...
where ...
group by 列1,列2.... --根据某列、多列进行分组
having cond
order by
1 查询各部门平均工资
select deptno , avg(sal)
from emp
group by deptno
【结论】:统计函数在有分组的情况下,统计的就是每个分组里边多行数据
没有分组的情况下,就是统计全表
在select 中出现的列,必须在group by中出现 ,除了统计函数
2 查询平均薪水大于2000的部门
select deptno , avg(sal)
from emp
where avg(sal) > 2000
group by deptno
第 3 行出现错误:
ORA-00934: 此处不允许使用分组函数
where 里边不允许使用分组函数进行判断
使用having
select deptno , avg(sal)
from emp
group by deptno
having avg(sal) > 2000
3 求10号部门员工的平均薪水
select deptno , avg(sal)
from emp
where deptno = 10
group by deptno
having
select deptno , avg(sal)
from emp
group by deptno
having deptno = 10
4 having与where的区别
select ..
from emp
where cond
group ...
havin cond
order by ...
where能做的having也能做,where不能做的having也能做
结论:能用where就别用having
1 从from 的表 emp 拿出数据
2 逐行筛选,通过where条件来筛选 , 结果集1
3 分组,并且计算统计函数 ,结果集2
4 再进行筛选,having的条件,通过having的条件就留下,得到结果集3
5 排序 得到结果集
如果一开始不通过where筛选,后边计算量大