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.表连接
where和on内连接返回的数据是两表关联上的数据
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;