select 2*3 from dual; --求年薪 select ename,sal, sal*12 from emp; --别名 select ename,sal, sal*12 as "年薪" from emp; select ename,sal, sal*12 "年薪" from emp; --员工一年总收入 select * from emp; select ename,sal, sal*12+comm as "年总收入" from emp; --注意:含有任何null值的数学表达式最后的结果都为null --字符串连接符 || select ename||'员工姓名' from emp; --处理一个字符串中含有单引号的情况 :使用2个单引号表示一个单引号 select ename||'员工''姓名' from emp; --含有任何null值的字符串表达式中,null被当作空字符串处理 select empno, ename||mgr from emp; --求员工每个级别顶薪 select hisal*12 as "员工年顶薪" from salgrade; /* distinct 消除重复值 */ --求emp表中的部门列表 select distinct deptno from emp; select deptno, job from emp; select distinct deptno, job from emp;--去除deptno, job 组合起来的重复值 --null值 --求奖金为null的员工信息 select * from emp where comm is null; --求奖金不为null的员工信息 select * from emp where comm is not null; /* in */ --求员工编号在某一个集合内的值 select * from emp where empno in (7369,7499,7521) select * from emp where empno not in (7369,7499,7521) /* oracle 日期 */ select * from emp; --求入职日期在1982-1-23后入职的人 select * from emp where hiredate > '23-1月-82'; /* like */ --查询员工 名字第二个字面为A的人 select * from emp where ename like '_A%'; --查询名字中含有 % 等通配符的数据时,使用转义字符 \ (\%) select * from emp where ename like '%\%%'; --查询1987年入职的人 select * from emp where hiredate>='1-1月-87' and hiredate<='31-12月-87'; select * from emp where hiredate like '%87%' /* order by*/ select * from emp order by deptno asc,sal desc; /*常用函数*/ --lower() select empno, Lower(ename) from emp; --查询名字带有 “A“ 或 "a"的员工 select * from emp where ename like '%A%' or ename like '%a%'; select * from emp where Lower(ename) like '%a%'; --Upper(); 小写转大写 select Upper('wepull') from dual; --Substr select Substr('wepull',2,3) from dual; --epu select Substr('wepull',2) from dual; --epull select Substr(ename,2) from emp; --Chr() 某个ASCII码值对应的字符 select Chr(97) from dual; -- a -- Ascii()函数 --例子:求一个字符的ASCII码值 select Ascii('a') from dual; --97 --常用数值函数 select round(23.652) from dual --24 select round(23.652,2) from dual --23.65 select round(23.652,-1) from dual --20 select round(493.652,-2) from dual --500 --to_char() select to_char(456123.45,'L999,999.99') from dual-- ¥456,123.00 --to_char()对日期的转换 select sysdate from dual; select to_char(sysdate,'YYYY/MM/DD') from dual; --to_date()函数 --例子:将1985年2月14日8:00以后入职的雇员信息取出 select * from emp where hiredate > to_date('1985-02-14 8:00','YYYY-MM-DD HH:MI') --to_number()函数 --求薪水<于1200的人 select * from emp where sal<to_number('$1,200','$9,999') --nvl 处理空值 select ename, sal*12+comm as "一年总收入" from emp select ename, sal*12+nvl(comm,0) as "一年总收入" from emp ---聚合函数/组函数 select * from emp; --emp表中deptno数量 select count(deptno) from emp; select count(distinct deptno) as "部门总数" from emp; --group by --求每个部门的最大工资 select deptno ,max(sal) from emp group by deptno; --求每个部门中职位的最大工资 select deptno ,job,max(sal) from emp group by deptno , job; ---求每个部门工资最高人信息 select ename,deptno,sal from emp where (deptno,sal)in (select deptno ,max(sal) from emp group by deptno); --方法二 select * from emp join (select deptno ,max(sal) max_sal from emp group by deptno ) t on (emp.deptno=t.deptno and emp.sal=t.max_sal) --having select deptno, avg(sal) from emp group by deptno having avg(sal)>2500 ---子查询 --求工资最高的人的信息 select * from emp where sal=( select max(sal) from emp ); --rownum(分页) --查询emp表前5条记录 select ename,rownum from emp where rownum<=5; --查询emp表第5条以后记录 select * from (select empno, ename,rownum as r from emp) where r>5; --rownum 与排序 select empno,ename,sal ,rownum from emp order by sal; select empno,ename,sal ,rownum from (select empno,ename,sal from emp order by sal) 上司 --自连接 --求emp表中员工的姓名和对应的上司(mgr) select * from emp; select e1.ename, e2.ename from emp e1,emp e2 where e1.mgr=e2.empno; --交叉连接 select ename from emp; select dname from dept; select ename,dname from emp ,dept; --结果为笛卡尔乘积 --SQL1999 语法 select ename,dname from emp cross join dept; --连接查询 create table a( id int primary key, name nvarchar2(20) ); select * from a; insert into a values (1,'凤姐'); insert into a values (3,'犀利哥'); insert into a values (5,'春哥'); insert into a values (6,'曾哥'); insert into a values (7,'平平'); create table b( id int primary key, info nvarchar2(20) ) insert into b values (1,'深圳'); insert into b values (2,'武汉'); insert into b values (6,'成都'); select * from a; select * from b; select * from a left outer join b on a.id=b.id;--左外连接 select * from a right outer join b on (a.id=b.id);--右外连接 select * from a full join b on (a.id=b.id);--全连接 (左外连接+右外连接) select * from a inner join b on (a.id=b.id) --内连接 --非等值连接 --查询出雇员名字和薪水等级(2个表连接查询) select * from emp; select * from salgrade; select e.ename ,e.sal ,s.grade from emp e join salgrade s on (e.sal between s.losal and s.hisal) --查询出雇员名字,及对应的部门名称,薪水等级(3个表连接查询) select e.ename, d.dname, s.grade from emp e join dept d on(e.deptno=d.deptno) join salgrade s on (e.sal between s.losal and s.hisal) --练习 --求部门中薪水最高的人名。 select * from emp e; select e.deptno, max(e.sal) from emp e group by deptno ; select e.ename ,t.deptno,e.sal from emp e join (select e.deptno, max(e.sal) max_sal from emp e group by deptno) t on (e.deptno=t.deptno and e.sal =max_sal) --求部门平均薪水等级? select deptno, avg(sal) from emp e group by deptno; select * from salgrade; select t.deptno, t.avg_sal, s.grade from salgrade s join (select deptno, avg(sal) avg_sal from emp e group by deptno) t on(t.avg_sal between s.losal and s.hisal ); --求哪些人是经理 select * from emp; select * from emp where mgr in (select mgr from emp); select * from emp where mgr in (select distinct mgr from emp); --平均薪水最高的部门编号与薪水 --第一步:先求出部门平均薪水 select e.deptno ,avg(sal) from emp e group by e.deptno; --第二步:求出平均薪水最高值 select max(t.avg_sal) from (select e.deptno ,avg(sal) avg_sal from emp e group by e.deptno) t --综合 select deptno ,avg_sal from (select e.deptno ,avg(sal) avg_sal from emp e group by e.deptno) t where t.avg_sal = ( select max(t.avg_sal) from (select e.deptno ,avg(sal) avg_sal from emp e group by e.deptno) t ) --方法二: select deptno ,avg_sal from (select e.deptno ,avg(sal) avg_sal from emp e group by e.deptno) t where avg_sal =(select max(avg(sal)) from emp group by deptno ) --注意 :组函数嵌套只能嵌套2层 select * from emp; --比普通员工的最高薪水还要高的经理人名称 -- 1.先求普通员工的最高薪水? select max(sal) from emp e where e.empno not in (select mgr from emp where mgr is not null ) --2.求比上面的值要大,并且还是经理人 select e.ename,e.sal from emp e where e.empno in (select distinct mgr from emp where mgr is not null ) and e.sal> ( select max(sal) from emp e where e.empno not in (select distinct mgr from emp where mgr is not null ) ); --复制表 create table emp as select * from scott.emp where 1<>1;--只复制结构 create table emp as select * from scott.emp ;--复制数据 create table dept as select * from scott.dept ; create table salgrade as select * from scott.salgrade ; create table bonus as select * from scott.bonus ; select * from emp ---Orcle 高级部分 --视图 select * from scott.emp; create view emp_view as select empno, ename,sal from scott.emp; select * from emp_view; drop view emp_view; --查询每个部门的名称、总人数、平均工资、最低工资的员工名字。 select dept.dname from demp; select deptno, count(empno) ,avg(sal),min(sal) from emp group by deptno ; --综合: 3张表连接查询 select d.dname, t.deptno, t.c, t.avg_sal,t.min_sal ,e.ename from dept d join (select deptno, count(empno) c ,avg(sal) avg_sal,min(sal) min_sal from emp group by deptno ) t on (d.deptno=t.deptno) join emp e on (e.sal=t.min_sal and e.deptno=t.deptno) --把上面结果封装成视图 create or replace view deptInfo_view as select d.dname, t.deptno, t.c, t.avg_sal,t.min_sal ,e.ename from dept d join (select deptno, count(empno) c ,avg(sal) avg_sal,min(sal) min_sal from emp group by deptno ) t on (d.deptno=t.deptno) join emp e on (e.sal=t.min_sal and e.deptno=t.deptno) -- select * from deptinfo_view; --------- --外键约束 drop table t_type; create table t_type( id int primary key, typeName varchar2(20) ) drop table t_book; create table t_book( id int primary key, name varchar2(20) , tid int , constraint FK_tid foreign key (tid) references t_type(id)--字段级的外键约束,不用加foreign key ) -- select * from user_tables; select table_name from user_tables; insert into t_type values (1,'言情类'); insert into t_type values (2,'计算机类'); insert into t_type values (3,'言武侠类'); select * from t_book t insert into t_book values (1,'小磊子的情书',1); insert into t_book values (2,'凤姐的韵事',1); insert into t_book values (3,'干露露的视频',2); insert into t_book values (4,'java自学成才',2); insert into t_book values (5,'刘德华的情歌',3); -------- --视图中使用DML的规定(不重要) create or replace view book_view as select id,name from t_book; -- select * from t_book select * from book_view; delete from book_view where id=4; --只读视图 create or replace view book_view as select id,name from t_book with read only; --序列 create or replace sequence my_sec; select my_sec.nextval from dual; select my_sec.currval from dual; create sequence book_sec; create table book( id number, name varchar2(50) ) alter table book add constraint PK_id primary key (id) select * from book; insert into book values (book_sec.nextval,'111'); insert into book values (book_sec.nextval,'222'); insert into book values (book_sec.nextval,'333'); insert into book values (book_sec.nextval,'444'); create sequence se_1 increment by 50 --次增长的幅度 50 start with 100 --从100开始 maxvalue 400 --最大400 minvalue 50 cycle --到最大值后循环 cache 2; select se_1.nextval from dual --索引 create index idx_book on book(name); drop index idx_book; --同义词 t_book create synonym t for t_book select * from t; drop synonym t; --- PL/SQL begin dbms_output.put_line('hello word'); end; --变量赋值 declare v_name varchar2(20):='wepull'; begin dbms_output.put_line(v_name); end; --复合类型变量 --记录类型 declare --定义一个记录类型 type book_rec is record( id int, name varchar2(20) ); b_rec book_rec; --声明一个变量是记录类型 begin select id ,name into b_rec from wepull.t_book where id=1; dbms_output.put_line(b_rec.id||b_rec.name); end; --%type declare v_id wepull.t_book.id%type ;--定义的变量v_id类型与t_book中的id列的类型一致 v_name wepull.t_book.name%type; begin /* v_id:=1; v_name:='wepull'; */ select id ,name into v_id,v_name from wepull.t_book where id=1; dbms_output.put_line(v_id); dbms_output.put_line(v_name); end; --rowtype declare v_book wepull.t_book%rowtype ;--定义的变量v_book类型与t_book中列的类型一致 begin select * into v_book from wepull.t_book where id=1; dbms_output.put_line('id: '||v_book.id); dbms_output.put_line('name: '||v_book.name); dbms_output.put_line('tid: '||v_book.tid); end; --嵌套表 select * from t_book; select * from wepull.t_book; declare type book_table_type is table of wepull.t_book%rowtype;--定义类型 v_book book_table_type:=book_table_type(); begin v_book.extend(5); select * into v_book(1) from wepull.t_book where id=1; dbms_output.put_line(v_book(1).id||' '||v_book(1).name); select * into v_book(2) from wepull.t_book where id=2; dbms_output.put_line(v_book(2).id||' '||v_book(2).name); end; / --流程控制语句 --if --单个if --1.查询用户输入的id的图书,如果图书的tid=1 则输出图书类型为言情类 declare v_id wepull.t_book.id%type:=&v_id; v_tid wepull.t_book.tid%type; begin select id,tid into v_id, v_tid from wepull.t_book where id=v_id; if (v_tid=1) then dbms_output.put_line('此id的图书为言情类'); end if; end; / --if else --1.查询用户输入的id的图书,如果图书的tid=1 则输出图书类型为言情类,否则输出不是言情类 declare v_id wepull.t_book.id%type:=&v_id; v_tid wepull.t_book.tid%type; begin select id,tid into v_id, v_tid from wepull.t_book where id=v_id; if (v_tid=1) then dbms_output.put_line(v_id|| ' :此id的图书为言情类'); else dbms_output.put_line(v_id|| ' :此id的图书不是言情类'); end if; end; / -- --if elsif --1.查询用户输入的id的图书, --如果图书的tid=1 则输出图书类型为言情类, --如果图书的tid=2 则输出图书类型为计算机类 --如果图书的tid=3 则输出图书类型为言武侠类 select * from wepull.t_type; declare v_id wepull.t_book.id%type:=&v_id; v_tid wepull.t_book.tid%type; begin select id,tid into v_id, v_tid from wepull.t_book where id=v_id; if (v_tid=1) then dbms_output.put_line(v_id|| ' :此id的图书为言情类'); elsif(v_tid=2)then dbms_output.put_line(v_id|| ' :此id的图书为计算机类'); elsif(v_tid=3)then dbms_output.put_line(v_id|| ' :此id的图书为武侠类'); end if; end; / --case declare v_id wepull.t_book.id%type:=&v_id; v_tid wepull.t_book.tid%type; v_typeName wepull.t_type.typeName%type; begin select tid into v_tid from wepull.t_book where id = v_id; v_typeName := case v_tid when 1 then '言情类' when 2 then '计算机类' when 3 then '武侠类' else '其他类' end; dbms_output.put_line('id: '||v_id); dbms_output.put_line('tid: '||v_tid); dbms_output.put_line('typeName: '||v_typeName); end; / -- --case 搜索方式 declare v_id wepull.t_book.id%type:=&v_id; v_tid wepull.t_book.tid%type; v_typeName wepull.t_type.typeName%type; begin select tid into v_tid from wepull.t_book where id = v_id; v_typeName := case when v_tid=1 then '言情类' when v_tid=2 then '计算机类' when v_tid=3 then '武侠类' else '其他类' end; dbms_output.put_line('id: '||v_id); dbms_output.put_line('tid: '||v_tid); dbms_output.put_line('typeName: '||v_typeName); end; / --循环 --循环1---Loop --求 1+2+....+100=? declare v_i number:=0; v_sum number:=0; begin loop v_i:=v_i+1; v_sum:=v_sum+v_i; exit when(v_i=100); end loop; dbms_output.put_line('1+2+....+100='||v_sum); end; / --循环1---while --求 1+2+....+100=? declare v_i number:=0; v_sum number:=0; begin while(v_i<100) loop v_i:=v_i+1; v_sum:=v_sum+v_i; end loop; dbms_output.put_line('1+2+....+100='||v_sum); end; / --循环1---for --求 1+2+....+100=? declare v_i number:=0; v_sum number:=0; begin for v_i in 1..100 loop v_sum:=v_sum+v_i; end loop; dbms_output.put_line('1+2+....+100='||v_sum); end; / -- declare v_i number:=0; v_sum number:=0; begin for int in 1..100 loop v_i:=v_i+1; v_sum:=v_sum+v_i; end loop; dbms_output.put_line('1+2+....+100='||v_sum); end; / --goto declare v_i number:=0; v_sum number:=0; begin for v_i in 1..10 loop dbms_output.put_line('当前i为: '||v_i); if(v_i=5) then goto endloop; end if; end loop; <<endloop>> dbms_output.put_line('此时v_i=5,退出了循环体'); end; --null语句 --goto declare v_i number:=0; v_sum number:=0; begin for v_i in 1..10 loop dbms_output.put_line('当前i为: '||v_i); if(v_i=5) then goto endloop; end if; end loop; <<endloop>> null; end; --游标 --使用游标取出emp表总前10人的信息。 select * from scott.emp; declare --第一步:声明游标 cursor emp_cursor is select * from scott.emp where rownum<=10; emp_record scott.emp%rowtype; begin --第二步:打开游标 open emp_cursor; --第三步:从游标中取数据 loop fetch emp_cursor into emp_record;--每取出一条数据,指针自动下移 exit when(emp_cursor%notfound);--最后次取数据失败 dbms_output.put_line(emp_record.empno|| ' ' ||emp_record.ename); end loop; --第四步:关闭游标 close emp_cursor; end; / --错误例子 declare --第一步:声明游标 cursor emp_cursor is select * from scott.emp where rownum<=10; emp_record scott.emp%rowtype; begin --第二步:打开游标 open emp_cursor; --第三步:从游标中取数据 loop fetch emp_cursor into emp_record;--每取出一条数据,指针自动下移 dbms_output.put_line(emp_record.empno|| ' ' ||emp_record.ename); exit when(emp_cursor%notfound);--最后次取数据失败 end loop; --第四步:关闭游标 close emp_cursor; end; / --使用游标取出emp表总前10人的信息。 while declare --第一步:声明游标 cursor emp_cursor is select * from scott.emp where rownum<=10; emp_record scott.emp%rowtype; begin --第二步:打开游标 open emp_cursor; --第三步:从游标中取数据 fetch emp_cursor into emp_record; while(emp_cursor%found)loop dbms_output.put_line(emp_record.empno|| ' ' ||emp_record.ename); fetch emp_cursor into emp_record; end loop; --第四步:关闭游标 close emp_cursor; end; / --使用游标取出emp表总前10人的信息。 for 必须掌握 declare --第一步:声明游标 cursor emp_cursor is select * from scott.emp where rownum<=10; emp_record scott.emp%rowtype; begin for emp_rec in emp_cursor loop dbms_output.put_line(emp_rec.empno|| ' ' ||emp_rec.ename); end loop; end; / --使用游标取出emp表总指定job 和 deptno的员工信息。 select * from scott.emp declare --第一步:声明游标 cursor emp_cursor(v_job scott.emp.job%type,v_deptno scott.emp.deptno%type) is select * from scott.emp where job=v_job and deptno=v_deptno; emp_record scott.emp%rowtype; begin for emp_rec in emp_cursor('CLERK',30) loop dbms_output.put_line(emp_rec.empno|| ' ' ||emp_rec.ename); end loop; end; / --模糊查询 select PATINDEX('%abb%','abcaabbeeabb') from dual; select * from scott.emp where regexp_like(ename, '[AS]MITH');--SMITH select * from scott.emp where ename like 'SMITH'; --游标的update操作 --更新指定图书的名字 declare cursor book_cursor is select * from t_book for update; --v_id t_book.id%type:=v_id; v_name t_book.name%type:=&v_name; begin for book_rec in book_cursor loop if(book_rec.tid=1) then update t_book set name=v_name where current of book_cursor; end if; end loop; end; / --隐式游标(了解) --更新指定图书的名字,如果该图书没有找到,则打印”查无此图书”。 declare v_name t_book.name%type:=&v_name; v_id t_book.id%type:=&v_id; begin update t_book set name=v_name where id=v_id; if(sql%found) then dbms_output.put_line('修改成功: '||v_id||' '||v_name); elsif(sql%notfound) then dbms_output.put_line('没有指定id的图书 '); end if; end; / -------------存储过程 create or replace procedure p1 as v_name t_book.name%type:='言情'; v_id t_book.id%type:=1; begin update t_book set name=v_name where id =v_id; if(sql%found) then dbms_output.put_line('修改成功'); end if; end; / --调用存储过程 exec p1; select * from t_book; begin p1; end; / --带参数的存储过程 --求1...N的和 (N为入参) create or replace procedure p2(v_number in number) as v_sum number:=0; v_i number:=0; begin for v_i in 0..v_number loop v_sum:=v_sum+v_i; end loop; dbms_output.put_line(v_sum); end; --调用 begin p2(100); end; / --带参数的存储过程 --求1...N的和 (v_number为入参,v_sum为出参) create or replace procedure p3(v_number in number,v_sum out number) as begin v_sum :=0; for v_i in 0..v_number loop v_sum:=v_sum+v_i; end loop; dbms_output.put_line('存储过程中打印:'||v_sum); end; --调用 declare v_sum number; begin p3(100,v_sum); dbms_output.put_line('调用打印:'||v_sum); end; / --函数 无参 create or replace function my_fun return date as v_date date; begin select sysdate into v_date from dual; return v_date; end; / --调用 select my_fun() from dual; --- declare v_date date; begin v_date:=my_fun(); dbms_output.put_line(v_date); end; / --函数 带参数 --根据id查询出图书名字 create or replace function getName(v_id t_book.id%type) return t_book.name%type as v_name t_book.name%type; begin select name into v_name from t_book where id = v_id; return v_name; end; / --调用 declare v_name t_book.name%type; begin v_name:=getName(2); dbms_output.put_line(v_name); end; / --触发器 create table book_log( username varchar2(10), action varchar2(10), adate date ) select * from a; create or replace trigger trigger_book after insert or update or delete on scott.a begin if inserting then insert into book_log values (user,'insert',sysdate); elsif updating then insert into book_log values (user,'update',sysdate); elsif deleting then insert into book_log values (user,'delete',sysdate); end if; end; / --测试 select * from a; select * from book_log; insert into a values (8,'龙磊的铃声'); update a set name='龙磊' where id = 8; delete from a set name='龙磊' where id = 8; --行触发器 create or replace trigger trigger_book after insert or update or delete on scott.a for each row begin if inserting then insert into book_log values (user,'insert',sysdate); elsif updating then insert into book_log values (user,'update',sysdate); elsif deleting then insert into book_log values (user,'delete',sysdate); end if; end; / -- update a set name=name||'2'; delete from book_log; select * from book_log; select * from a; select * from emp; --异常处理(了解) declare v_empno scott.emp.empno%type:=&v_empno; v_emp_rec emp%rowtype; begin select * into v_emp_rec from scott.emp where scott.emp.empno=v_empno; dbms_output.put_line(v_emp_rec.empno||' '||v_emp_rec.ename); exception when no_data_found then dbms_output.put_line('没有此编号的员工 '); end; / declare v_deptno scott.emp.deptno%type:=&v_deptno; v_emp_rec emp%rowtype; begin select * into v_emp_rec from scott.emp where scott.emp.deptno=v_deptno; dbms_output.put_line(v_emp_rec.empno||' '||v_emp_rec.ename); exception when no_data_found then dbms_output.put_line('没有此编号的员工 '); when too_many_rows then dbms_output.put_line('select 语句返回了多行数据 '); end;
with e as 用法:
其实就是把一大堆重复用到的sql语句放在with as里面,取一个别名,后面的查询就可以用它,这样对于大批量的sql语句起到一个优化的作用,而且清楚明了。 with e as (select * from smc_sql ) select * from e where e.id=2; with as优点 增加了sql的易读性,如果构造了多个子查询,结构会更清晰; 更重要的是:“一次分析,多次使用”,这也是为什么会提供性能的地方,达到了“少读”的目标