oracle 基本sql语句合集

目录

1、常用查询语句

2.单行函数

2.1字符型函数

2.2数字型函数

2.3日期型函数

2.4转换函数

3.分组函数

         3.1 count

3.2 avg 求平均值函数

3.3 sum 求和

3.4 min

3.5 max

3.6 group by一般与分组函数一起使用

3.7 分组函数嵌套

4.多表查询

4.1 相等连接

4.2 自连接

4.3不等连接

4.4 外连接

5.子查询   一个查询依赖另一个查询.

5.1 单行子查询

5.2多行子查询

1).使用in操作符的多行子查询:

2).使用all操作符的多行子查询   

         3).使用any操作符的多行子查询

4).多列子查询

5.3 其他语句中使用子查询

1).建表语句中使用子查询

2).insert语句中使用子查询

3).删除语句中使用子查询  

4).update语句中使用子查询

6.dml(数据操作语言)

1)insert

2)update

3)delete

代码版(可以直接赋值粘贴到sqlplus下运行)


1、常用查询语句

--1.查看emp表的所有信息
select * from emp;

--2.查看有哪些部门,部门有哪些人,每个人的工作是什么
select dname,ename,job from emp,dept where emp.deptno=dept.deptno;
select dname,ename,job from emp,dept where emp.deptno=dept.deptno order by dname;

--3.给每个员工多发600元,看每个员工要发多少钱   ★ 
select sal+nvl(comm,0)+600 "月薪"  from emp;

--4.给老板打印工资表(仅sal基本工资,老板不认识英文,除了名字)
select ename "姓名",job "职称",sal "工资" from emp;

--5.字符串连接
select ename||' annual salary is '||sal "Employee' Salary" from emp;

--6.emp表中有几个部门
select count(distinct deptno) 部门数  from emp;

--7.查询每个部门中的岗位有哪些  distinct dname,job作用于后面所有的列
select distinct dname,job from emp,dept where emp.deptno=dept.deptno;

--8.查找smith的薪水,工作,所在部门
select sal+nvl(comm,0),job,dname from emp,dept where emp.deptno=dept.deptno and ename='SMITH';

--9.查找在82年1月23号入职的员工姓名、雇佣日期  --原题为1号 但1号无记录改成23号
--方法1
select ename,hiredate from emp where hiredate = '23-1月-82';
--方法2:
--session当前会话有效 scott有资格
alter session set NLS_DATE_FORMAT='yyyy-mm-dd'; 
select ename,hiredate from emp where hiredate = '1982-01-23';
--方法3::
select ename,hiredate from emp where hiredate=to_date('1982-01-01','yyyy-mm-dd');

--10.查找薪水在2000-3000的雇员姓名和薪水
select ename,sal from emp where sal between 2000 and 3000;
select ename,sal from emp where sal>=2000 and sal<=3000;

--11.显示首字母为S的员工的姓名、雇用日期  %
/*
%:可以匹配任意长度的内容
"_":可以匹配一个长度的内容
*/
select ename,hiredate from emp where ename like 'S%';

--12.显示第3个字符为O的所有员工姓名和工资
select ename,sal from emp where ename like '__O%';

--13.查找没有绩效的员工姓名
/*
广义绩效工资又称绩效加薪、奖励工资  也即绩效就是奖金comm
*/
select ename from emp where comm is null;

--14.查找员工姓名、工资、绩效、年收入
select ename,sal,comm,sal*12+nvl(comm,0) 年收入 from emp;

--15.查找员工岗位是SALESMAN,CLERK,MANAGER的员工信息
select * from emp where job in('SALESMAN','CLERK','MANAGER');

--16.查找员工岗位不是SALESMAN,CLERK,MANAGER的员工信息
select * from emp where job not in('SALESMAN','CLERK','MANAGER');

--看到此 2019年6月5日01:39:33

--17.按sal升序排列,如果有工资相同的,按姓名字符升序排列
select * from emp order by sal,ename;

--18.选择在部门30中的员工的所有信息
select * from emp where deptno=30;

--19.列出职位为(MANAGER)的员工编号、姓名
select empno,ename from emp where job='MANAGER';

--20.找出奖金高于工资的员工
select * from emp where comm>sal;

--21.找出每个员工奖金和工资的总和
select ename,sal+nvl(comm,0) from emp;

--22.找出部门10中的经理(MANAGER)和部门20中的普通员工(CLERK)
select * from emp where (deptno=10 and job='MANAGER') or (deptno=20 and job='CLERK');
--或者
select * from emp where deptno=20 and job='CLERK' union select * from emp where deptno=10 and job='MANAGER';

--23.找出部门10中既不是经理,也不是普通员工,而且工资大于等于2000的员工
select * from emp where job not in('MANAGER','CLERK') and sal>=2000 and deptno=10;

--24.找出没有奖金的不同工作
select distinct(job) from emp where comm is null;

--25.找出没有奖金或者奖金低于500的员工
select * from emp where comm is null or comm<500;
--更方便
select * from emp where nvl(comm,0)<500;


2.单行函数

2.1字符型函数

1)upper 查询结果字符串全转大写
select coll from test;
select upper(coll) from test;


2)lower 查询结果字符串全转小写
select ename from emp;
select lower(ename) from emp;


3)initcap 每个单词的首字母大写
select coll from test;
select initcap(coll) from test;


4)concat 字符串拼接
select concat('hello',' world') from dual;
--输出:hello

--语句输出存字符的方法
--隐藏列标题
set heading off
select '************当前用户下的表************' from dual;
set heading on


5)substr 字符串截取
--substr(s,i,[j])从字符串s第i位开始截取j个子字符串,省略j则一直截取到s末尾   (下标1开始 写0等价于写1)
select substr('helloworld',6) from dual;
--上行输出world
select substr('helloworld',6,3) from dual;
--上行输出wor

6)length 字符串长度
select length('hello') from dual;
--输出5 

7)replace(s1,s2,[s3]),用字符串s3替换在s1中出现的所有字符串s2.默认s3为空字符串,即起删除作用
select replace('helloworld','low') from dual;
--输出helorld
select replace('helloworld','low','XXX') from dual;
--输出helXXXorld

8)instr instr(s1,s2[,i][,j]) s1,s2字符串 i,j整数 
--返回字符串s2在字符串s1中第j次出现的位置,s1中搜索起点i,
--i为负数则搜索从右向左进行,但返回的位置还是按从左到右计算
select instr('XXXhelXXXhelXXXhel','hel',4,2) from dual;
--输出10
select instr('XXXhelXXXhelXXXhel','hel',5,2) from dual;
--输出16
select instr('XXXhelXXXhelXXXhel','hel',-5,2) from dual;
--从右往左搜索  输出4
select instr('XXXhelXXXhelXXXhel','hel',-5,3) from dual;
--无 返回0


2.2数字型函数

1).round(num,n)  四舍五入数字num保留n位小数  (n默认值0 n为负数 小数点前n位的数字是精确的即可) 
select round(3.14159) from dual;
--输出:3
select round(3.14159,4) from dual;
--输出:3.1416
select round(333.14159,-1) from dual;
--输出:330
select round(335.14159,-1) from dual;
--输出:340

2).trunc(num,n) 作用同round 不过不四舍五入,只是去尾
select trunc(3.14159) from dual;
--输出:3
select trunc(3.14159,4) from dual;
--输出:3.1415
select trunc(333.14159,-1) from dual;
--输出:330
select trunc(339.14159,-1) from dual;
--输出:330

3).mod(m,n) 返回m%n  取余
select mod(8,4) from dual;
--输出:0
select mod(8,3) from dual;
--输出:2


2.3日期型函数

1).months_between(d1,d2) 返回d1,d2之间的月数    oracle里天转月时,除以基数为31
--日期类型默认  '08-9月 -81'
select months_between(to_date('2019-4-29','yyyy-mm-dd'),to_date('2019-4-30','yyyy-mm-dd')) from dual;
-- -.03225806   解释:d1<d2 返回负  d1与d2相差不到一个月,就一天。。1/31月 1/31=03225806
select months_between(to_date('2019-5-29','yyyy-mm-dd'),to_date('2019-4-29','yyyy-mm-dd')) from dual;
--输出:1  正好相差一个月  d1>d2 输出正数

2).add_months(d,i) 返回日期d加上i个月之后的结果
select add_months(to_date('2019-5-29','yyyy-mm-dd'),5) from dual;
--输出:29-10月-19
select add_months(sysdate,5) from dual;
--输出:29-9月 -19

补:sysdate 系统时间
select sysdate from dual;
--输出:29-4月 -19

3).next_day(date,char) 返回日期date开始的下一个星期char的日期
-- date参数为日期型, 
-- char:为1~7或Monday/Mon~Sunday/   1星期天  2星期1 ... 7星期6
--比如今天星期1
select next_day(sysdate,2) from dual;
--输出:06-5月 -19    而下个星期1也确实是5月6号
--日期格式恶心死了,还是初始化时改下吧  
select next_day('2019-04-29','MONDAY') from dual;
--周中的日无效 数据库语言中文导致  改成下面写法即可
select next_day('2019-04-29','星期一') from dual;
-- 输出:2019-05-06

4).last_day(d) 返回日期d所在月的最后一天
--不写04也行 ^_^
select last_day('2019-4-5') from dual;
--输出:2019-04-30

5).systime 
-- select systime from dual;
-- oracle 似乎并没有systime 获取时间可以这样
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
--年
select  to_char(sysdate, 'yyyy' )  from dual; 
--月 
select  to_char(sysdate, 'MM' )  from dual; 
--日
select  to_char(sysdate, 'dd' )  from dual;  
--季
select  to_char(sysdate, 'Q')  from dual;  
--周--按日历上的那种,每年有52或者53周 
select  to_char(sysdate, 'iw')  from dual; 


6) systimestamp  得到当前详细日期时间信息
select systimestamp from dual;
--输出:29-4月 -19 10.45.11.100000 上午 +08:00  
select to_char(systimestamp,'YYYY-MM-DD HH24:MI:SS.FF9') from dual;
--输出:2019-04-29 10:46:48.808000000

7). current_timestamp
select current_timestamp from dual;
--输出:29-4月 -19 10.48.51.733000 上午 +08:00
--设置完时区再执行
alter session set time_zone='UTC';
select to_char(current_timestamp,'YYYY-MM-DD HH24:MI:SS') from dual;
--输出:2019-04-29 02:51:32
select to_char(sysdate,'YYYY-MM-DD HH24:MI:SS') from dual;
--输出:2019-04-29 10:52:14    说明修改时区不会影响  sysdate的执行


2.4转换函数

1).to_char(date,'format') 日期转换为指定的格式 
select to_char(sysdate,'yyyy-mm-dd') from dual;
--输出:2019-04-29

2).to_char(数字,'format') 数字转换为字符串
select to_char(25436.78,'$999,999.99') from dual;
--输出:$25,436.78

3).to_date(字符串,['fmt'])  字符串转日期
select to_date('05-06---2019','mm-dd---yyyy') from dual;
--输出:2019-05-06
--前面第9题
select ename,hiredate from emp where hiredate=to_date('1982-01-23','yyyy-mm-dd');


3.分组函数
3.1 count 计数

--1.公司中有多少员工
select count(empno) from emp;
--2.公司中有多少员工由经理管理
select count(e1.empno) from emp e1,emp e2 where e1.mgr=e2.empno and e2.job='MANAGER';  
-3.查看部门号为10的员工数
select count(empno) from emp where deptno=10;
--4.查看有多少个岗位
select count(distinct job) from emp;

3.2 avg 求平均值函数

--1.查看公司的平均工资
select avg(sal) from emp;
--2.查看公司每个部门的平均工资
select deptno,avg(sal) from emp group by deptno;


3.3 sum 求和

--查看这个月工人的工资支出
select sum(sal) from emp;

3.4 min

--查看公司的最少工资
select min(sal) from emp;

3.5 max

--1.查看公司最高的工资
select max(sal) from emp;

--2.查找雇佣第一员工和最迟雇佣员工
select ename,hiredate from emp where hiredate in(select max(hiredate) from emp union select min(hiredate) from emp);


3.6 group by一般与分组函数一起使用

--查看公司每个部门的平均工资
select deptno,avg(sal) from emp group by deptno;

3.7 分组函数嵌套

--1.查找工作不是president的员工中按工作分类不同工作的最低平均工资和最高平均工资
select max(avg(sal)) 平均工资 from emp where job != 'PRESIDENT' group by job;
select min(avg(sal)) 平均工资 from emp where job != 'PRESIDENT' group by job;

select job 工作,avg(sal) 平均工资 from emp where job != 'PRESIDENT' group by job having avg(sal) in(
    select max(avg(sal)) 平均工资 from emp where job != 'PRESIDENT' group by job
    union
    select min(avg(sal)) 平均工资 from emp where job != 'PRESIDENT' group by job
);

--方法二,不输出工作名称
select max(avg(sal)) 最高平均工资,min(avg(sal)) 最低平均工资 from emp where job != 'PRESIDENT' group by job;

--2. 查出高于本部门员工平均工资的员工信息
--各部门平均工资
select deptno,avg(sal) from emp  group by deptno;
--大于本部门平均工资
select * from emp e1 where sal > (select avg(sal) from emp e2 where e2.deptno=e1.deptno) order by e1.deptno;

4.多表查询

4.1 相等连接

--1.查询每个员工所属部门和所在的具体地点
select ename 员工,dname 部门,loc 部门地址 from emp,dept where emp.deptno=dept.deptno;

--2.工资为1600元或者以上的员工所属的部门和地点
select ename,sal,dname,loc from emp,dept where emp.deptno=dept.deptno and sal>=1600;

4.2 自连接

--1. 每个分析员及上司的姓名  (注意分析员只是众多职业其中之一 ANALYST)
select e1.ename 分析员,e2.ename 上级 from emp e1,emp e2 where e1.mgr=e2.empno and e1.job='ANALYST';

4.3不等连接

--1.查询显示工资级别在3-5级之间的所有员工
--最低
select losal from salgrade where grade=3;
--最高
select hisal from salgrade where grade=5;
--查询
select * from emp where sal between (select losal from salgrade where grade=3) and (select hisal from salgrade where grade=5);

--2.查询员工姓名、工资、工资级别
select ename,sal,grade from emp,salgrade where sal>=losal and sal<=hisal;

4.4 外连接

内连接:★
     格式1:显式的内连接
         select a.*,b.* from a [inner] join b on ab的连接条件
     格式2:隐式的内连接
         select a.*,b.* from a,b where ab的连接条件

 外连接:★
     左外连接:★
         select a.*,b.* from a left [outer] join b on 连接条件;
        意思:
            先展示join左边的(a)表的所有数据,根据条件关联查询 join右边的表(b),符合条件则展示出来,不符合以空白展示.
     右外连接:
         select a.*,b.* from b right [outer] join a on 连接条件;
         意思:
             先展示join右边的表(a)表的所有数据,根据条件关联查询join左边的表(b),符合条件则展示出来,不符合以空白展示.

--on子句
--1.查询员工编号、员工姓名、工资、部门号、部门地址   e.deptno为。。
select e.empno,e.ename,e.sal,e.deptno,d.loc from emp e join dept d on (e.deptno=d.deptno) order by loc;
--14行无空白

--左外连接
-- 2.同上  左外连接dept为主
select emp.empno,emp.ename,emp.sal,dept.deptno,loc from dept left outer join emp on (emp.deptno=dept.deptno);
--15行有空白
--先展示dept表的所有信息 然后根据条件展示右边emp表的信息,没有的null,  反正join左边表的每条记录至少打印一行(都要展示)
-- 而40号部门正好没人。所以有一空行

--右外连接
--3.同上 同上  右外连接dept为主
select emp.empno,emp.ename,dept.deptno,dept.loc from emp right outer join dept on (emp.deptno=dept.deptno);
--15行有空白
--先展示join右边表dept的所有记录  同样40号部门没人也要打印,对应的emp表内容为空白

5.子查询   一个查询依赖另一个查询.

5.1 单行子查询

--1. 查询与smith相同职位的人
select * from emp where job =(select job from emp where ename='SMITH') and ename != 'SMITH';

--2.查询职位与'SMITH'相同,而工资不超过ADAMS的员工
select * from emp where job =(select job from emp where ename='SMITH') and ename != 'SMITH' 
and sal<=(select sal from emp where ename='ADAMS');

--3.查询最高工资的员工姓名、岗位、工资
select ename,job,sal from emp where sal=(select max(sal) from emp);

--4.查询高于本部门员工平均工资的员工姓名、部门号、工资、部门平均工资 ★★
--强大的临时表  select deptno,avg(sal) avgsal from emp group by deptno  查询结果作为临时表来与emp进行连接查询
col avgsal format 9999.00;
select ename,e1.deptno,sal,avgsal 
    from emp e1,(select deptno,avg(sal) avgsal from emp group by deptno) e2
    where e1.deptno=e2.deptno and sal>avgsal order by deptno;

5.2多行子查询


1).使用in操作符的多行子查询:

--eg:查询每个部门工资最高的员工姓名、工作、工资(部门最高工资不重复时逻辑才对,否则就是工资等于某个部门最高工资的员工信息)
select ename,job,sal from emp where sal in (select max(sal) from emp group by job);

--查询与部门号10相同的工作
--本意
select distinct job from emp where job in (select job from emp where deptno=10);
--其实
select distinct job from emp where deptno=10;

2).使用all操作符的多行子查询   

--查询比所有10号部门员工工资低的员工的姓名、工作、工资(两种方法)  修改原题
select ename,job,sal from emp where sal <(select min(sal) from emp where deptno=10);
select ename,job,sal from emp where sal < all(select sal from emp where deptno=10);

3).使用any操作符的多行子查询

--查询比任意部门平均工资高的员工姓名、工作、薪水(两种方法)         修改原题
select ename,job,sal from emp where sal >(select min(avg(sal)) from emp group by deptno);
select ename,job,sal from emp where sal > any(select avg(sal) from emp group by deptno);

4).多列子查询

--1.查询与smith工作、部门相同的员工
select * from emp where ename!='SMITH' and job=(select job from emp where ename='SMITH') and deptno=(select deptno from emp where ename='SMITH');


--2.如何显示高于自己部门平均工资的员工信息
select * from emp e1 where sal>(select avg(sal) from emp e2 where e2.deptno=e1.deptno);


5.3 其他语句中使用子查询

1).建表语句中使用子查询

--复制查询结果到新表
create table mytable(id,name,sal) as (select empno,ename,sal from emp);
--table 不可省略
drop table mytable;
-- 完全复制   20号部门的信息全部复制过去
create table mytable as    select * from emp where deptno=20;

--可以用此来备份表  或者新建一个备份表

--只是复制表结构 where后条件为假即可
create table myemp as select * from emp where 1=2;

2).insert语句中使用子查询

--建立新表   --最后一行的,不能写 必须省略
create table employee(
    name varchar2(10),
    sal number(7,2),
    job varchar2(10)
);
--插入数据  将查询结果批量插入  没有 as 也不能有as  DDL语句才有as
insert into employee select ename,sal,job from emp where deptno=10;

3).删除语句中使用子查询  

--删除工资大于工作为'CLERK'(该工资唯一)的员工信息
delete from employee where sal > (select sal from employee where job='CLERK');

4).update语句中使用子查询

update employee set sal=(select sal from employee where job ='CLERK');

6.dml(数据操作语言)

DML:数据操作语言
      操作对象:记录

1)insert

--1)完全插入 指明要插入的具体字段值
insert into dept(deptno,dname,loc) values(50,'DEVELOPMENT','DETROIT');

--不指明具体字段,则按序每个字段都要插入一个值  用to_date函数指明日期格式,这样无论系统默认日期格式如何,都不会报错
insert into emp values(2296,'AROMANO','SALESMAN',7782,to_date('03-2月 1997','DD-MON,YYYY'),1300,null,10);


-- 2) 省略字段值
-- dept表共三个字段 DEPTNO DNAME LOC  仅主键DEPTNO不允许为空
--省略方法:列举列名,忽略有空值的列
insert into dept(deptno,dname) values(70,'FINANCE');
--省略列名 用null填充
insert into dept values(60,'MIS',null);


2)update

--改现有行
--更改7698号雇员的工作和部门,与第7499号雇员改为相同
--先备份
--7698 BLAKE      MANAGER         7839 1981-05-01       2850                    30
--多个列值 中间必须,不能是and
--update emp set job='MANAGER',deptno=30 where empno=7698;   

--update set语句可以列对应赋值
update emp set (job,deptno)=(select job,deptno from emp where empno=7499) where empno=7698;    

3)delete

--删除所有职位为salsman的员工信息,并练习rollback,commit
--先备份
create table salsEmp as select * from emp where job='SALESMAN';
--后期还原
-- insert into emp select * from salsEmp;

--开始删除
delete emp where job='SALESMAN';
--查询就剩10行了 SALESMAN job的全没了
-- 此时 rollback
rollback
--再次查询job为SALESMAN的又恢复了

delete emp where job='SALESMAN';
commit;
--查询 记录删除了
rollback;--无论怎么rollback记录都没有了。。。  还好提前有备份


--还原
insert into emp select * from salsEmp;





代码版(可以直接赋值粘贴到sqlplus下运行)

​
--1.查看emp表的所有信息
select * from emp;

--2.查看有哪些部门,部门有哪些人,每个人的工作是什么
select dname,ename,job from emp,dept where emp.deptno=dept.deptno;

--3.给每个员工多发600元,看每个员工要发多少钱   ★ 
select sal+nvl(comm,0)+600 "月薪"  from emp;

--4.给老板打印工资表(仅sal基本工资,老板不认识英文,除了名字)
select ename "姓名",job "职称",sal "工资" from emp;

--5.字符串连接
select ename||' annual salary is '||sal "Employee' Salary" from emp;

--6.emp表中有几个部门
select count(distinct deptno) 部门数  from emp;

--7.查询每个部门中的岗位有哪些  distinct dname,job作用于后面所有的列
select distinct dname,job from emp,dept where emp.deptno=dept.deptno;

--8.查找smith的薪水,工作,所在部门
select sal+nvl(comm,0),job,dname from emp,dept where emp.deptno=dept.deptno and ename='SMITH';

--9.查找在82年1月23号入职的员工姓名、雇佣日期  --原题为1号 但1号无记录改成23号
--方法1
select ename,hiredate from emp where hiredate = '23-1月-82';
--方法2:
--session当前会话有效 scott有资格
alter session set NLS_DATE_FORMAT='yyyy-mm-dd'; 
select ename,hiredate from emp where hiredate = '1982-01-23';
--方法3::
select ename,hiredate from emp where hiredate=to_date('1982-01-01','yyyy-mm-dd');

--10.查找薪水在2000-3000的雇员姓名和薪水
select ename,sal from emp where sal between 2000 and 3000;
select ename,sal from emp where sal>=2000 and sal<=3000;

--11.显示首字母为S的员工的姓名、雇用日期  %
/*
%:可以匹配任意长度的内容
"_":可以匹配一个长度的内容
*/
select ename,hiredate from emp where ename like 'S%';

--12.显示第3个字符为O的所有员工姓名和工资
select ename,sal from emp where ename like '__O%';

--13.查找没有绩效的员工姓名
/*
广义绩效工资又称绩效加薪、奖励工资  也即绩效就是奖金comm
*/
select ename from emp where comm is null;

--14.查找员工姓名、工资、绩效、年收入
select ename,sal,comm,sal*12+nvl(comm,0) 年收入 from emp;

--15.查找员工岗位是SALESMAN,CLERK,MANAGER的员工信息
select * from emp where job in('SALESMAN','CLERK','MANAGER');

--16.查找员工岗位不是SALESMAN,CLERK,MANAGER的员工信息
select * from emp where job not in('SALESMAN','CLERK','MANAGER');

--17.按sal升序排列,如果有工资相同的,按姓名字符升序排列
select * from emp order by sal,ename;

--18.选择在部门30中的员工的所有信息
select * from emp where deptno=30;

--19.列出职位为(MANAGER)的员工编号、姓名
select empno,ename from emp where job='MANAGER';

--20.找出奖金高于工资的员工
select * from emp where comm>sal;

--21.找出每个员工奖金和工资的总和
select ename,sal+nvl(comm,0) from emp;

--22.找出部门10中的经理(MANAGER)和部门20中的普通员工(CLERK)
select * from emp where (deptno=10 and job='MANAGER') or (deptno=20 and job='CLERK');
--或者
select * from emp where deptno=20 and job='CLERK' union select * from emp where deptno=10 and job='MANAGER';

--23.找出部门10中既不是经理,也不是普通员工,而且工资大于等于2000的员工
select * from emp where job not in('MANAGER','CLERK') and sal>=2000 and deptno=10;

--24.找出没有奖金的不同工作
select distinct(job) from emp where comm is null;

--25.找出没有奖金或者奖金低于500的员工
select * from emp where comm is null or comm<500;
--更方便
select * from emp where nvl(comm,0)<500;




--2.单行函数
--2.1字符型函数
--1)upper 查询结果字符串全转大写
select coll from test;
select upper(coll) from test;
--2)lower 查询结果字符串全转小写
select ename from emp;
select lower(ename) from emp;
--3)initcap 每个单词的首字母大写
select coll from test;
select initcap(coll) from test;
--4)concat 字符串拼接
select concat('hello',' world') from dual;
--输出:hello

--语句输出存字符的方法
--隐藏列标题
set heading off
select '************当前用户下的表************' from dual;
set heading on
--5)substr 字符串截取
--substr(s,i,[j])从字符串s第i位开始截取j个子字符串,省略j则一直截取到s末尾   (下标1开始 写0等价于写1)
select substr('helloworld',6) from dual;
--上行输出world
select substr('helloworld',6,3) from dual;
--上行输出wor

--6)length 字符串长度
select length('hello') from dual;
--输出5 

--7)replace(s1,s2,[s3]),用字符串s3替换在s1中出现的所有字符串s2.默认s3为空字符串,即起删除作用
select replace('helloworld','low') from dual;
--输出helorld
select replace('helloworld','low','XXX') from dual;
--输出helXXXorld

--8)instr instr(s1,s2[,i][,j]) s1,s2字符串 i,j整数 
--返回字符串s2在字符串s1中第j次出现的位置,s1中搜索起点i,
--i为负数则搜索从右向左进行,但返回的位置还是按从左到右计算
select instr('XXXhelXXXhelXXXhel','hel',4,2) from dual;
--输出10
select instr('XXXhelXXXhelXXXhel','hel',5,2) from dual;
--输出16
select instr('XXXhelXXXhelXXXhel','hel',-5,2) from dual;
--从右往左搜索  输出4
select instr('XXXhelXXXhelXXXhel','hel',-5,3) from dual;
--无 返回0


--2.2数字型函数
--9.round(num,n)  四舍五入数字num保留n位小数  (n默认值0 n为负数 小数点前n位的数字是精确的即可) 
select round(3.14159) from dual;
--输出:3
select round(3.14159,4) from dual;
--输出:3.1416
select round(333.14159,-1) from dual;
--输出:330
select round(335.14159,-1) from dual;
--输出:340

--10.trunc(num,n) 作用同round 不过不四舍五入,只是去尾
select trunc(3.14159) from dual;
--输出:3
select trunc(3.14159,4) from dual;
--输出:3.1415
select trunc(333.14159,-1) from dual;
--输出:330
select trunc(339.14159,-1) from dual;
--输出:330

--11.mod(m,n) 返回m%n  取余
select mod(8,4) from dual;
--输出:0
select mod(8,3) from dual;
--输出:2


--2.3日期型函数
--12.months_between(d1,d2) 返回d1,d2之间的月数    oracle里天转月时,除以基数为31
--日期类型默认  '08-9月 -81'
select months_between(to_date('2019-4-29','yyyy-mm-dd'),to_date('2019-4-30','yyyy-mm-dd')) from dual;
-- -.03225806   解释:d1<d2 返回负  d1与d2相差不到一个月,就一天。。1/31月 1/31=03225806
select months_between(to_date('2019-5-29','yyyy-mm-dd'),to_date('2019-4-29','yyyy-mm-dd')) from dual;
--输出:1  正好相差一个月  d1>d2 输出正数

--13.add_months(d,i) 返回日期d加上i个月之后的结果
select add_months(to_date('2019-5-29','yyyy-mm-dd'),5) from dual;
--输出:29-10月-19
select add_months(sysdate,5) from dual;
--输出:29-9月 -19

--13.1补:sysdate 系统时间
select sysdate from dual;
--输出:29-4月 -19

--14.next_day(date,char) 返回日期date开始的下一个星期char的日期
-- date参数为日期型, 
-- char:为1~7或Monday/Mon~Sunday/   1星期天  2星期1 ... 7星期6
--比如今天星期1
select next_day(sysdate,2) from dual;
--输出:06-5月 -19    而下个星期1也确实是5月6号
--日期格式恶心死了,还是初始化时改下吧  
select next_day('2019-04-29','MONDAY') from dual;
--周中的日无效 数据库语言中文导致  改成下面写法即可
select next_day('2019-04-29','星期一') from dual;
-- 输出:2019-05-06

--15.last_day(d) 返回日期d所在月的最后一天
--不写04也行 ^_^
select last_day('2019-4-5') from dual;
--输出:2019-04-30

-- 16.systime 
-- select systime from dual;
-- oracle 似乎并没有systime 获取时间可以这样
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
--年
select  to_char(sysdate, 'yyyy' )  from dual; 
--月 
select  to_char(sysdate, 'MM' )  from dual; 
--日
select  to_char(sysdate, 'dd' )  from dual;  
--季
select  to_char(sysdate, 'Q')  from dual;  
--周--按日历上的那种,每年有52或者53周 
select  to_char(sysdate, 'iw')  from dual; 


--17 systimestamp  得到当前详细日期时间信息
select systimestamp from dual;
--输出:29-4月 -19 10.45.11.100000 上午 +08:00  
select to_char(systimestamp,'YYYY-MM-DD HH24:MI:SS.FF9') from dual;
--输出:2019-04-29 10:46:48.808000000

--18. current_timestamp
select current_timestamp from dual;
--输出:29-4月 -19 10.48.51.733000 上午 +08:00
--设置完时区再执行
alter session set time_zone='UTC';
select to_char(current_timestamp,'YYYY-MM-DD HH24:MI:SS') from dual;
--输出:2019-04-29 02:51:32
select to_char(sysdate,'YYYY-MM-DD HH24:MI:SS') from dual;
--输出:2019-04-29 10:52:14    说明修改时区不会影响  sysdate的执行


--2.4转换函数
-- 19.to_char(date,'format') 日期转换为指定的格式 
select to_char(sysdate,'yyyy-mm-dd') from dual;
--输出:2019-04-29

--20.to_char(数字,'format') 数字转换为字符串
select to_char(25436.78,'$999,999.99') from dual;
--输出:$25,436.78

--21.to_date(字符串,['fmt'])  字符串转日期
select to_date('05-06---2019','mm-dd---yyyy') from dual;
--输出:2019-05-06
--前面第9题
select ename,hiredate from emp where hiredate=to_date('1982-01-23','yyyy-mm-dd');


-- 3.分组函数
--3.1 count: select count(*) from emp;
--22.公司中有多少员工
select count(empno) from emp;
--23.公司中有多少员工由经理管理
select count(e1.empno) from emp e1,emp e2 where e1.mgr=e2.empno and e2.job='MANAGER';  
--24.查看部门号为10的员工数
select count(empno) from emp where deptno=10;
--25.查看有多少个岗位
select count(distinct job) from emp;

--3.2 avg 求平均值函数
--26.查看公司的平均工资
select avg(sal) from emp;
--27.查看公司每个部门的平均工资
select deptno,avg(sal) from emp group by deptno;


--3.3 sum 求和
--28.查看这个月工人的工资支出
select sum(sal) from emp;

--3.4 min
--29.查看公司的最少工资
select min(sal) from emp;

--3.5 max
--30.查看公司最高的工资
select max(sal) from emp;

--31.查找雇佣第一员工和最迟雇佣员工
select ename,hiredate from emp where hiredate in(select max(hiredate) from emp union select min(hiredate) from emp);


--3.6 group by一般与分组函数一起使用
--见前面例27

--3.7 分组函数嵌套
--32.查找工作不是president的员工中按工作分类不同工作的最低平均工资和最高平均工资
select max(avg(sal)) 平均工资 from emp where job != 'PRESIDENT' group by job;
select min(avg(sal)) 平均工资 from emp where job != 'PRESIDENT' group by job;

select job 工作,avg(sal) 平均工资 from emp where job != 'PRESIDENT' group by job having avg(sal) in(
	select max(avg(sal)) 平均工资 from emp where job != 'PRESIDENT' group by job
	union
	select min(avg(sal)) 平均工资 from emp where job != 'PRESIDENT' group by job
);

--方法二,不输出工作名称
select max(avg(sal)) 最高平均工资,min(avg(sal)) 最低平均工资 from emp where job != 'PRESIDENT' group by job;

--33. 查出高于本部门员工平均工资的员工信息
--各部门平均工资
select deptno,avg(sal) from emp  group by deptno;
--大于本部门平均工资
select * from emp e1 where sal > (select avg(sal) from emp e2 where e2.deptno=e1.deptno) order by e1.deptno;

--4.多表查询
--4.1 相等连接
--34.查询每个员工所属部门和所在的具体地点
select ename 员工,dname 部门,loc 部门地址 from emp,dept where emp.deptno=dept.deptno;

--35.工资为1600元或者以上的员工所属的部门和地点
select ename,sal,dname,loc from emp,dept where emp.deptno=dept.deptno and sal>=1600;

--4.2 自连接
--36. 每个分析员及上司的姓名  (注意分析员只是众多职业其中之一 ANALYST)
select e1.ename 分析员,e2.ename 上级 from emp e1,emp e2 where e1.mgr=e2.empno and e1.job='ANALYST';

--4.3不等连接
--37.查询显示工资级别在3-5级之间的所有员工
--最低
select losal from salgrade where grade=3;
--最高
select hisal from salgrade where grade=5;
--查询
select * from emp where sal between (select losal from salgrade where grade=3) and (select hisal from salgrade where grade=5);

--38.查询员工姓名、工资、工资级别
select ename,sal,grade from emp,salgrade where sal>=losal and sal<=hisal;

--4.4 外连接
-- 内连接:★
-- 	格式1:显式的内连接
-- 		select a.*,b.* from a [inner] join b on ab的连接条件
-- 	格式2:隐式的内连接
-- 		select a.*,b.* from a,b where ab的连接条件

-- 外连接:★
-- 	左外连接:★
-- 		select a.*,b.* from a left [outer] join b on 连接条件;
-- 		意思:
-- 			先展示join左边的(a)表的所有数据,根据条件关联查询 join右边的表(b),符合条件则展示出来,不符合以空白展示.
-- 	右外连接:
-- 		select a.*,b.* from b right [outer] join a on 连接条件;
-- 		意思:
-- 			先展示join右边的表(a)表的所有数据,根据条件关联查询join左边的表(b),符合条件则展示出来,不符合以空白展示.

--on子句
--40.查询员工编号、员工姓名、工资、部门号、部门地址   e.deptno为。。
select e.empno,e.ename,e.sal,e.deptno,d.loc from emp e join dept d on (e.deptno=d.deptno) order by loc;
--14行无空白

--左外连接
-- 41.同上  左外连接dept为主
select emp.empno,emp.ename,emp.sal,dept.deptno,loc from dept left outer join emp on (emp.deptno=dept.deptno);
--15行有空白
--先展示dept表的所有信息 然后根据条件展示右边emp表的信息,没有的null,  反正join左边表的每条记录至少打印一行(都要展示)
-- 而40号部门正好没人。所以有一空行

--右外连接
--42.同上 同上  右外连接dept为主
select emp.empno,emp.ename,dept.deptno,dept.loc from emp right outer join dept on (emp.deptno=dept.deptno);
--15行有空白
--先展示join右边表dept的所有记录  同样40号部门没人也要打印,对应的emp表内容为空白

-- 5.子查询   一个查询依赖另一个查询.
--5.1 单行子查询
--43. 查询与smith相同职位的人
select * from emp where job =(select job from emp where ename='SMITH') and ename != 'SMITH';

--44.查询职位与'SMITH'相同,而工资不超过ADAMS的员工
select * from emp where job =(select job from emp where ename='SMITH') and ename != 'SMITH' 
and sal<=(select sal from emp where ename='ADAMS');

--45.查询最高工资的员工姓名、岗位、工资
select ename,job,sal from emp where sal=(select max(sal) from emp);

--45_2 查询高于本部门员工平均工资的员工姓名、部门号、工资、部门平均工资
--强大的临时表  select deptno,avg(sal) avgsal from emp group by deptno  查询结果作为临时表来与emp进行连接查询
col avgsal format 9999.00;
select ename,e1.deptno,sal,avgsal 
	from emp e1,(select deptno,avg(sal) avgsal from emp group by deptno) e2
	where e1.deptno=e2.deptno and sal>avgsal order by deptno;

--5.2多行子查询
--1.使用in操作符的多行子查询:
--eg:查询每个部门工资最高的员工姓名、工作、工资
select ename,job,sal from emp where sal in (select max(sal) from emp group by job);

--46 查询与部门号10相同的工作
--本意
select distinct job from emp where job in (select job from emp where deptno=10);
--其实
select distinct job from emp where deptno=10;

-- 2.使用all操作符的多行子查询   
--47.查询比所有10号部门员工工资低的员工的姓名、工作、工资(两种方法)  修改原题
select ename,job,sal from emp where sal <(select min(sal) from emp where deptno=10);
select ename,job,sal from emp where sal < all(select sal from emp where deptno=10);

--3.使用any操作符的多行子查询
--48.查询比任意部门平均工资高的员工姓名、工作、薪水(两种方法)		 修改原题
select ename,job,sal from emp where sal >(select min(avg(sal)) from emp group by deptno);
select ename,job,sal from emp where sal > any(select avg(sal) from emp group by deptno);

--4.多列子查询
--49.查询与smith工作、部门相同的员工
select * from emp where ename!='SMITH' and job=(select job from emp where ename='SMITH') and deptno=(select deptno from emp where ename='SMITH');


--50.如何显示高于自己部门平均工资的员工信息
select * from emp e1 where sal>(select avg(sal) from emp e2 where e2.deptno=e1.deptno);


--5.3 其他语句中使用子查询
-- 1.建表语句中使用子查询
--复制查询结果到新表
create table mytable(id,name,sal) as (select empno,ename,sal from emp);
--table 不可省略
drop table mytable;
-- 完全复制   20号部门的信息全部复制过去
create table mytable as	select * from emp where deptno=20;


--2.insert语句中使用子查询
--建立新表   --最后一行的,不能写 必须省略
create table employee(
	name varchar2(10),
	sal number(7,2),
	job varchar2(10)
);
--插入数据  将查询结果批量插入
insert into employee select ename,sal,job from emp where deptno=10;

--3.删除语句中使用子查询  
--删除工资大于工作为'CLERK'(该工资唯一)的员工信息
delete from employee where sal > (select sal from employee where job='CLERK');

--4.update语句中使用子查询
update employee set sal=(select sal from employee where job ='CLERK');


-- 6.dml(数据)
	-- DML:数据操作语言
	-- 	操作对象:记录
--1)insert 完全记录插入   
--指明要插入的具体字段值
insert into dept(deptno,dname,loc) values(50,'DEVELOPMENT','DETROIT');

--不指明具体字段,则按序每个字段都要插入一个值  用to_date函数指明日期格式,这样无论系统默认日期格式如何,都不会报错
insert into emp values(2296,'AROMANO','SALESMAN',7782,to_date('03-2月 1997','DD-MON,YYYY'),1300,null,10);


-- 2) 省略字段值
-- dept表共三个字段 DEPTNO DNAME LOC  仅主键DEPTNO不允许为空
--省略方法:列举列名,忽略有空值的列
insert into dept(deptno,dname) values(70,'FINANCE');
--省略列名 用null填充
insert into dept values(60,'MIS',null);


--update
--改现有行
--更改7698号雇员的工作和部门,与第7499号雇员改为相同
--先备份
--7698 BLAKE      MANAGER         7839 1981-05-01       2850                    30
--多个列值 中间必须,不能是and
--update emp set job='MANAGER',deptno=30 where empno=7698;   

--update set语句可以列对应赋值
update emp set (job,deptno)=(select job,deptno from emp where empno=7499) where empno=7698;	

--delete
--删除所有职位为salsman的员工信息,并练习rollback,commit
--先备份
create table salsEmp as select * from emp where job='SALESMAN';
--后期还原
-- insert into emp select * from salsEmp;

--开始删除
delete emp where job='SALESMAN';
--查询就剩10行了 SALESMAN job的全没了
-- 此时 rollback
rollback
--再次查询job为SALESMAN的又恢复了

delete emp where job='SALESMAN';
commit;
--查询 记录删除了
rollback;--无论怎么rollback记录都没有了。。。  还好提前有备份


--还原
insert into emp select * from salsEmp;

​

  • 31
    点赞
  • 241
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值