oracle 查询模板

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Haiqiang1995/article/details/79137955

1单表查询

select,(子查询)from,(子查询) where 列过滤条件(子查询);

例:

标量子查询

select  empno,

      ename,

      job,

      sal,

      (select dname from dept where dept.deptno = emp.deptno) deptno

 from emp;

例:

自连接:

select deptno, sal

 from emp a

 where sal = (select min(sal) from emp b where a.deptno = b.deptno);

半连接

select * from emp where deptno in(select deptno from dept)

例:

单列数据恢复

update emp_fuck a set a.sal =(select sal from emp b where b.empno=a.empno);

删除重复数据

1.delete t_name

 where rowid in (select rowid

                  from (select row_number() over(partition by empno order by empno) rn

                          from emp_2b)

                 where rn = 1);

2.delete t_namea

 where exists (select null

         from emp_2b b

        where a.empno = b.empno

          and a.rowid < b.rowid);

3.delete t_name

 where rowid not in / in

      (select max(rowid) / min(rowid) from test group by object_id);

2.表管理

查询建表语句

例:

select dbms_metadata.get_ddl('TABLE','t_name','t_user') from dual;

分页框架

select*

 from (select *

         from (select a.*, rownum rn from (需要分页的语句)a)

        where rownum <= 10)

 where rn >= 1;

3.字符函数

||拼接或者concat

例:

select empno||ename||sal from emp;

select concat(concat(empno,ename),sal) from emp;

或者

select concat(empno||ename,sal) from emp;

字符函数--模糊查询

select ename from emp where substr(ename,3,1)='A';

select ename from emp where instr (ename,'A',3,1)=3;

select ename from emp where ename like '__A%';

 

替换函数

例:

replace:把ab当做整体进行替换

select replace ('abcdad','ab','c') from dual;

translate:求某个字符的个数

select length((select translate('192.168.10.101 ','.'||'192.168.10.101 ','.') fromdual)) from dual;

4.日期函数

转化函数date‘2017-08-01<=>to_date('数值''格式')

month_between--求两个月的时间差

例:select months_between(soursedate , targetdate )*31 from dual;

trunc--截取日期格式

select trunc(sysdate,'mm') from dual;

add_month(日期,num)--增加月份5

常用语法

明天的范围

select to_char(trunc(sysdate+1),'yyyy-MM-ddhh24:mi:ss'),to_char(trunc(sysdate+2),'yyyy-MM-dd hh24:mi:ss') from dual;

下个月

select   to_char(add_months(trunc(sysdate,'MM'),1),'yyyy-MM-ddhh24:mi:ss'),to_char(add_months(trunc(sysdate,'MM'),2),'yyyy-MM-dd hh24:mi:ss')

 from dual;

下个季度标准写法应该是q

selec tadd_months(trunc(sysdate,'q'),3),add_months(trunc(sysdate,'q'),6) from dual;

select to_char(sysdate,'ddd') from dual;--返回今年的第多少天

select to_char(sysdate,'q') from dual;--返回第几个季度

select to_char(sysdate,'d') from dual; --返回本周的第多少天

select to_char(sysdate,'ww') from dual ; --返回今年的第多少周

select to_char(sysdate,'w') from dual ;--返回本月过了第几周

last_day(日期)--最后一天

next_day(日期)--下一天

含有日期的单表查询模板

select。。。

from table_name

where hiredate < to_date('数字', '格式')

and hiredate >= to_date('数字', '格式')

and。。。

group by。。。

having。。。

order by ... desc/[asc];

执行顺序:--from --where-- group by --having-- select --order by

含有case...when...then....end的查询模板

select to_char(hiredate,'yyyy')年份,

聚合函数(case...when...then....end)as。。,

聚合函数(case...when...then....end)as。。,

聚合函数(case...when...then....end)as。。

from table_name

where日期字段<。。。

and日期字段>。。。

group by to_char(hiredate,'yyyy'),。。。;

:

select to_char(consumedate,'yyyy-mm')月份,

      content消费类型,

      count(id)消费次数,

      sum(account)消费总额,

      count(distinct cardno)消费人数,

      sum(account)/count(distinct cardno)人均消费金额

 from t_consume

 where consumedate> to_date('20160501', 'yyyy-mm-dd')

  and consumedate < to_date('20160801', 'yyyy-mm-dd')

 group by to_char(consumedate,'yyyy-mm'), content

 order by content;

 

5.表连接

whereon内连接返回的数据是两表关联上的数据

select a...,b.....  <=> select a...,b..... <=> select a.....,b......

from表名 a from 表名 a from表名a,表名b

[inner]join表名 b [inner] join表名 b where a.字段=b.字段

on a.字段 = b.字段 on a.字段 = b.字段and a/b.字段=。。。;

and a.字段 =。。。; where a.字段 =。。。;

执行顺序

---from--where---group by--join --select ---order by--

子查询模板

select a...,b...,别名

from() a

inner join dept b

on a.链接字段 = b.链接字段;

+

(select字段, count(*) 别名

from表名

where。。。

and。。。

group by字段) a 

一般a表为条件的筛选表

---group by后面的字段一般要少,这样的优点可以根据单表或者部分表的筛选条件使结果集变少,大大加快了链接的速度

例:

select b.dname, count(b.dname) from (select deptno

from emp a

where a.hiredate >

to_date('19820101','yyyymmdd')

and a.hiredate <

to_date('19830101','yyyymmdd')) c,

dept b where c.deptno = b.deptno

group by b.dname;

子查询转化

select b.dname, cnt

from(select deptno, count(*) cnt

from emp

where hiredate > to_date('19820101', 'yyyymmdd')

and hiredate < to_date('19830101', 'yyyymmdd')

group by deptno) a

inner join dept b

on a.deptno = b.deptno;

外链接left<outer>join (左外连接)

外链接返回的是主表的所有数据,以及子表能够关联上的数据,关联不上的数据用null代替

常规模板

select

from a Left join b

ona.id=b.id

anda.name ..

andb.name ..

where a...

and b...

group by ..

having..

order by ..

执行顺序-- from --主表where--join--子表where--group by --select --order by

半连接模板

select a... from   a(外表) where (a.字段,a.字段。。)

 in

  (select (b.字段,b.字段。。)  from b(内表) where  b.....)

---其中外表可以为多表的链接,只要保证和内表的链接字段可以建立链接就可以了

内表也可以为复杂的查询只要可以给外表返回所需字段就可以了

exists用法

select a...,a..... from a where a.....

and exists(select *** from b where a...=b....   and b..... ); 

---其中***随意,不去执行子查询的结果,判断能否关联上正确会返回,错误不返回

例:

select * from

emp where job in(select job from emp where deptno=20);

<=>

select * from emp a where deptno=30

and exists(select null from emp b where a.job=b.job and deptno=20 );

反链接

只需要在in或者 exists之前加 not not in,如果子查询返回有空值的话,直接返回空

例:

SELECT* FROM EMP

WHERE mgr NOT IN (SELECT  mgr  FROM EMP WHERE DEPTNO = 10 AND mgr IS NOT NULL) OR  mgr IS  NULL;

--反连接,not exists

SELECT * FROM emp a WHERE NOT EXISTS

(SELECT NULL FROM emp b WHERE  a.mgr = b.mgr  AND  deptno = 10);

 

全外链接

full outer join全外连接两个表关联上的数据全部展示,关联不上的数据显示为空

标量子查询

emp表中的员工信息及其部门名称

例:select a.*, (select d name from dept b where a.deptno = b.deptno) from emp a;

--一个子查询在返回字段上就是标量子查询外面的表每返回一行数据就要执行一次里面的子查询语句,成为标量子查询标量子查询是一个天然的嵌套循环

他的执行计划一定是nl(nexted loop )

驱动表每返回一行数据,被驱动表都要还行一次

--标量子查询都可以改为外链接

例:select a.*,b.dname from emp a right join dept b on a.deptno=b.deptno;

 

求某个数据当中的排名第一的数据(考虑并列的情况)模板

select ct项目,snt金额

from(select b.*, rank() over(order by snt desc) rn

from(select分组字段 ct, count/sum(b.数据项)别名

from b

where b.date >= to_date('******', 'yyyymm')

and b.date < to_date('******', 'yyyymm')

and...

group by b.分组字段

order by别名 desc) b)

where rn = 1;

例:

select a.name会员姓名, a.handledate注册日期, snt总金额

 from t_user_info a

 join (select b.*, rank() over(order by snt desc) rn

         from (select cardno, sum(account) snt

                 from t_consume

                where consumedate >= to_date('201607', 'yyyymm')

                  and consumedate < to_date('201608', 'yyyymm')

                group by cardno

                order by snt desc) b) c

   on a.cardno = c.cardno

  and rn = 1;

 

case when嵌套模板 

select distinct (case when

[聚合函数](case when c.字段= '' then b.字段 end)

>< <> like in is .....

[聚合函数](case when c.字段 = '' then b.字段end)

then b.其他字段 end) as 别名

from t_name b

inner join t_name c

on b.链接字段= c.链接字段

group by b.分组字段;

例:

select distinct (case

when

max(case when c.name = '语文' then b.score end)

<max(case when c.name = '数学' then b.score end)

then

b.stuid

end)as学号

from t_score b

inner join t_course c

on b.courseid = c.courseid

group by b.stuid ;

 

in的模糊匹配模板

select distinct a.字段, a.字段,a....

from t_name a

inner join t_name c

on a.字段 = c.字段

and c.链接字段in (select b.链接字段 from t_name b where b.字段。。。)

and a.stuid<>'1';

例:

select distinct a.stuid, a.name

from t_stu a

inner join t_score c

on a.stuid = c.stuid

and c.courseid in (select b.courseid from t_score b where b.stuid = '1')

and a.stuid<>'1';

 

in/exists的完全匹配模板(a表中字段的域小于b中的域)

with as x(

select c# from t_name sc where s# x

)

select * from student

where not exists( select * from x

where not exists (

select * from sc where s#=student.s# and c#=c#));

<=>

select S#

 from t_name sc

 where C# in (select C# from SC where S# = 'x')

 group by S#

having count(*) = (select count(*) from sc where S# = 'x');

 

case when排名报表模板(分析函数)

例:

select

max(case when courseid='2' then stuid end)as "数学",

max(case when courseid='1' then stuid end)as "语文",

max(case when courseid='5' then stuid end)as "化学",

max(case when courseid='6' then stuid end)as "物理",

max(case when courseid='3' then stuid end)as "天文",

max(case when courseid='4' then stuid end)as "地理"

from

(select* from (select a.*,

dense_rank()over(partition by courseid order by score desc) rk

from t_score a)

where rk <= 2)

group by rk;

猜你喜欢

转载自blog.csdn.net/Haiqiang1995/article/details/79137955