查询现有数据库:select name from V$database;
解锁用户scott:alter user scott account unlock;
普通用户连接:conn scott
默认密码:tiger
普通管理员:system/system
超级管理员:Sys/sys
断开连接:disconnect
当前用户:show user
查看该用户下的所有对象:select * from tab;
dual表是oracle内虚拟的一个表,妙用很多
单行函数
模糊查询
%表示零个或多个字符
_ 表示一个字符
对于特殊符号可使用ESCAPE标识符来查找
select * from emp where ename like ‘%*_%‘ escape ‘*‘
上面的escape表示*后面的那个符号不被当成特殊字符处理,就是查找普通的_符号
Scott用户自带的表结构
雇员表EMP(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
部门表dept(deptno,dname,loc)
工资等级表salgrade(grade,losal,hisal)
奖金表BONUS(ENAME,JOB,SAL,COMM)
单表查询example
选择在部门30中员工的所有信息
select * from emp where deptno=30;
列出职位为(manager)的员工的编号,姓名
select empno,ename from emp where job=‘MANAGER‘
找出奖金高出工资的员工
select * from emp where comm>sal;
找出每个员工奖金和工资的总和
select ename,comm+sal from emp;
找出部门10中的经理(MANAGER)和部门20中的普通员工(CLERK);
找出部门10中既不是经理也不少普通员工,而且工资大于2000的员工
SELECT * FROM EMP WHERE DEPTNO=10 AND JOB NOT IN (‘MANAGER‘,‘CLERK‘) AND SAL>=2000;
找出有奖金的员工的不同工作
select distinct job from EMP where comm is not null and comm>0;
找出没有奖金或者奖金低于500的员工
select * from emp where comm<500 or comm is null;
显示雇员姓名,根据其服务年限,将最老的雇员排在最前面
select ename from emp order by hiredate;
字符函数
upper,lower(大写,小写)
initcap(将每个能识别的单词的第一个字母大写,其他小写,中间出息中文,空格都将视为一个单词)
concat(‘a‘,‘b‘); ‘a‘||‘b‘ 连接俩字符串
length()字符串长度
substr(‘abcde‘,length(‘abcde‘)-2,2) 从第三个字符开始取‘abcde’的2个字符,结果为‘cd‘,第三个值可缺省
replace(ename,‘A‘,a)将ename的所有A换为a
instr(‘Hello world‘,‘or‘)第二个字符串在第一个字符串中的位置(结果为8)
lpad(‘Smith‘,10,‘*‘) *****Smith
rpad(‘smith‘,10,‘*‘) Smith*****
trim(‘ Mr Smith ‘)过滤首尾空格
trim([BOTH|LEADING|TRAILING] ‘*‘ from ‘****ab***‘) ab
数值函数
round(419,-1) 精确到小数点后多少位,进行四舍五入,-1的结果为420
round(412.313,2)结果为412.31
mod(5,4) 取余,1
trunc类似round,截取时不进行四舍五入
日期函数
months_between(date1,date2),返回相差的月数date1-date2
add_months(to_date(‘19910522‘,‘yyyymmdd‘))增加一个月
next_day(sysdate,‘星期一‘)下一个星期一的日期
last_day(sysdate)对应月份的最后一天
转换函数
//sysdate---2015-03-16
to_char(sysdate,‘yyyy‘)2015
to_char(sysdate,‘fmyyyy-mm-dd‘)2015-3-16
to_char(sysdate,‘yyyy-mm-dd‘)2015-03-16
select to_char(sal,‘L999,999,999‘)from emp; ¥800 ¥3,000
to_char(sysdate,‘D‘)返回这是这周的第几天,注意这里返回的是美国习惯,即周日是第一天
to_number(‘13‘)
to_date(‘20051103‘,‘yyyymmdd‘)
通用函数
nvl(字段名,‘x’)该字段若为空值时,显示为X
nullif(表达式1,表达式2)如果表达式1等于表达式2,则返回空值,否则返回表达式1的值
nvl2(表达式,不为空设值,为空设值)
coalesce(表达式1,表达式2,表达式3)依次考察各参数表达式,遇到非null值即停止并返回该值
select empno,ename,sal,case deptno when 10 then ‘财务部‘ when 20 then ‘研发部‘ when 30 then ‘销售部‘ else‘未知部门‘ end
部门 from emp;
select empno,ename,sal,decode( deptno, ‘财务部‘, 20,‘研发部‘ ,30,‘销售部‘,‘未知部门‘ )部门 from emp;
练习:
1.找出每个月倒数第三天受雇的员工(如:2009-5-29)
select * from emp where hiredate+2=last_day(hiredate);
2.找出30年前的雇的员工
select * from emp where hiredate<=add_months(sysdate,-30*12);
3.所有员工名字前加上Dear ,并且首字母大写
select * from ‘Dear ‘|| initcap(ename) from emp;
4.找出姓名为5个字母的员工
select * from emp where length(ename)=5;
5.找出姓名中不带R这个字母的员工
select * from emp where ename not like ‘%R%‘;
6.显示所有员工的姓名的第一个字
select substr(ename,1,1) from emp;
7.显示所有员工,按名字第一个字母降序排列,若相同,则按工资升序排列
select ename,sal from emp order by substr(ename,1,1) desc,sal;
8.假设一个月为30天,找出所有员工的日薪,不计小数
select ename,round(sal/30)daily_sal from emp;
9.找到2月受雇的员工
select * from emp where to_char(hiredate,‘fmmm‘)=‘2‘;
10.列出员工加入公司的天数(四舍五入)
select ename,round(months_between(sysdate,hiredate)*30)from emp;
11.分别用case和decode函数列出员工所在的部门,deptno显示‘部门10’,deptno=20显示‘部门20’否则为‘其他部门’
select ename,case deptno when 10 then‘部门10‘ when 20 then ‘部门20‘ else ‘其他部门‘ end 部门 from emp;
select ename,decode(deptno,10,‘部门10‘,20,‘部门20‘,‘其他部门‘)部门 from emp;
分组函数
count
如果数据库表没有数据,count(*)返回的不是null,而是0
avg,max,min,sum
用avg算均值时,若为null,不算均数,如emp表中除了1400,300,500,0外,都为空值,算出来的值为550,此时可用nvl()函数强制分组函数处理空值
select avg(nvl(comm,0)) from emp;
group by 不允许出现在where中(用having)
select deptno,avg(sal) from emp group by deptno;
having 字句
select deptno,job,avg(sal) from emp where hiredate >=todate(‘1981-05-01‘,‘yyyy-mm-dd‘) group by deptno,job having avg(sal) >1200 order by deptno,job;
分组函数嵌套
select max(avg(sal)) from emp group by deptno;
练习:
1.统计各部门下工资大于500员工的平均工资表
select avg(sal) where sal>500 group deptno;
2.统计各部门下平均工资大于1600的部门
select deptno,avg(sal) from emp group by deptno having avg(sal)>1600;
3.算出部门30中薪水最高的员工薪水
select max(sal) from where deptno=30;
4.算出部门30中薪水最高的员工姓名
select ename from emp where sal=(select max(sal) from where deptno=30);
5.算出每个职位的员工数和最低工资
select job,min(sal),count(*)from emp group by job;
6.算出每个部门,每个职位的平均工资和平均奖金(平均值包括没有奖金)如果平均奖金大于300,显示‘奖金不错‘,如果平均奖金100到300,显示‘奖金一般‘,如果平均奖金小于100,显示“基本没有奖金”,按部门编号降序,平均工资降序排列
select deptno,job,avg(sal)平均工资,avg(nvl(comm,0))平均奖金,case when avg(nvl(comm,0))>=300 then ‘奖金不错‘ avg(nvl(comm,0))>100 and avg(nvl(comm,0))<300 then ‘奖金一般‘ else ‘基本没有奖金‘ end 奖金状况 from emp group by deptno,job order by deptno desc, avg(sal) desc;
7.列出员工表中每个部门的员工数,和部门no
select deptno,count(*) from emp group by deptno;
8.得到工资大于自己部门平均工资的员工信息
select * from emp e1,(select deptno,avg(sal)avgsal from emp group by deptno)e2 where e1.deptno=e2.deptno and e1.sal>e2.avgsal;
9.分组统计每个部门下,每种职位的平均奖金和总工资(包括奖金)
select deptno,job,avg(nvl(comm,0)),sum(sal+nvl(comm,0)) from emp group by deptno,job;