/*create table f0307 (
id number
,productname varchar2(100)
,parentid number);
insert into f0307 values ( 1,'汽车',null);
insert into f0307 values ( 2,'车身',1);
insert into f0307 values ( 3,'发动机',1);
insert into f0307 values ( 4,'车门',2);
insert into f0307 values (5,'驾驶舱',2);
insert into f0307 values (6,'行李舱',2);
insert into f0307 values ( 7,'气缸',3);
insert into f0307 values ( 8,'活塞',3);*/
select * from f0307;
select * from f0307 f1 full join f0307 f2
on f1.id = f2.parentid;
-----------------------------------------------------------------------------------------------------
select distinct a.id,decode(b.parentid,null,'NULL',b.parentid) parentid,a.productname,b.orderid from
(select id,lpad(' ',level*2,' ')||productname productname
,level
from f0307
start with id = 1
connect by prior id=parentid) a
join
(with tt as(
select f2.id id2,f2.parentid parentid2,f2.productname name2,
f3.id id3,f3.parentid parentid3,f3.productname name3,
decode(f1.id,null,null,f1.id||'->')||f2.id||'->'||f3.id orderid
from f0307 f1 full join f0307 f2 on f1.id = f2.parentid
left join f0307 f3
on f2.id = f3.parentid where f1.id = 1 or f1.id is null)
select tt.id2 id,tt.parentid2 parentid,tt.name2 productname,'1' orderid from tt where tt.id2 = 1
union all
select tt.id3,tt.parentid3,tt.name3,tt.orderid from tt where tt.id3 >=1) b
on a.id =b.id;
-----------------------------------------------QTingLJQ------------------------------------------------
select id,decode(parentid,null,'NULL',parentid) parentid,lpad(' ',level*3,' ')||productname productname,
case when level=1 then to_char(id)
when level=2 then parentid||'->'||id
when level=3 then 1||'->'||parentid||'->'||id
end orderid
from f0307
start with id=1
connect by prior id=parentid
-----------------------------------------------QTingXLJ------------------------------------------------
--sys_connect_by_path():反向拼接函数,例如sys_connect_by_path()
select id,decode(parentid,null,'NULL',parentid) parentid ,lpad(' ',level*2,' ')||productname as productname,
substr((sys_connect_by_path(id,'->')),3) orderid
from f0307
start with id=1
connect by prior id=parentid;
with auto(id,parentid,productname,orderid) as(
select
id,parentid,productname,to_char(id) orderid
from f0307 f1
where parentid is null
union all
select
f2.id,f2.parentid,f2.productname,
auto.orderid||'->'||f2.id
from auto join
f0307 f2
on auto.id=f2.parentid
)
select id,parentid,lpad(' ',level-1,' ')||productname as productname,
orderid
from auto
start with id=1
connect by prior id=parentid;
-----------------------------------------------QTingWGD------------------------------------------------
with aaa as(
select connect_by_root parentid as c
from f0307
start with parentid=1
connect by prior id=parentid)
select a1.id,
(case when parentid is null then 'NULL' end)上id
,productname 名,
(case when parentid is null then to_char(a1.id) end) 上级 from f0307 a1,
(select distinct id,
(case when c=parentid then parentid||'>'||id
when parentid is null then to_char(id)
else aaa.c||'>'||parentid||'>'||id end) a
from aaa,f0307) a2
where a1.id=1 and a1.id=a2.id
union all
select id,to_char(parentid),名,上级 from (
select b1.id,parentid,lpad(' ',level*2,' ')||productname as 名,
b2.a 上级,rownum r
from f0307 b1,(select distinct id,
(case when c=parentid then parentid||'->'||id
when parentid is null then to_char(id)
else aaa.c||'->'||parentid||'->'||id end) a
from aaa,f0307 ) b2 where b1.id=b2.id
start with parentid in (1,2)
connect by prior b1.id=b1.parentid) where r<=7;
-------------------------------------------------------------------------------------
--8.创建一个名为id_seq的升序Sequence,从10开始,递增10,最小值为10,最大值为100:
create sequence id_seq
start with 10
increment by 10
minValue 10
maxValue 100;
--9.创建序列id_seq2,开始值为100,增幅是2,
--最大值是1000,设置循环,序列中的序号不在内存中进行缓冲:
create sequence id_seq2
start with 100
increment by 2
maxValue 1000
nocache
cycle
;
select id_seq2.nextval from dual;
--10.创建一个1,3,5,7,9…30序列,设置循环,缓存数量为10个:
create sequence id_seq3
start with 1
increment by 2
maxValue 30
cache 10
cycle;
select id_seq3.nextval from dual;
create synonym synonym_name for table_name;
grant select on synonym_name to public;
----DBLink
-- 查看当前用户是否具有创建DBLink的权限
select * from user_sys_privs
where privilege like upper('%DATABASE LINK%');
-- 如果没有切换到sys,给当前用户赋予相关权限
-- 已经切换到sys
grant create public database link to scott;
grant drop public database link to scott;
-- 创建dblink
create database link dblink_1
connect to scott identified by "123456"
using '(description =
(address_list = (address=(protocol=tcp)(host= jiuze.top )(port=1521)))
(connect_data=(service_name=orcl))
)';
-- 查看数据中创建的dblink
select owner,object_name from dba_objects
where object_type='DATABASE LINK';
-- dblink的使用
-- 直接查询
select * from emp@dblink_1;
-- 同义词包装
create synonym remote_db for emp@dblink_1;
select * from remote_db;
-- 视图包装
create view v_remote_db as select * from emp@DBLINK_1;
select * from v_remote_db;
-- 数据库的启动与关闭
-- 习题回顾
-- 1.
select * from f07;
select distinct f.a,sum(f.b)over(partition by f.a) b,
decode(sum(decode(f.c,'X',1,0))over(partition by f.a),0,'Y',1,'1',2,'X') c
from f07 f order by f.a;
-- 2.
select * from f216
select sum(cnt) from
(select count(*)/2 cnt from f216 f1,f216 f2 where f1.numb !=f2.numb and f1.numb+f2.numb = 10
union all
select count(*) from f216 f1,f216 f2,f216 f3
where f1.numb+f2.numb+f3.numb=10
and f1.numb<f2.numb and f2.numb<f3.numb);
--3.查询学习‘c001’课程中优秀(91-100),良好(81-90),及格(60-80)各有多少人:
select cno,sum(case when score between 91 and 100 then 1 else 0 end) 优秀,
sum(case when score > 80 and score < 90 then 1 else 0 end) 良好,
sum(case when score between 60 and 80 then 1 else 0 end) 及格
from sc where cno = 'c001' group by cno;
-- 4.按各科平均成绩从低到高和及格率的百分数从高到低顺序:
select cno,avg(score),sum(case when score >= 60 then 1 else 0 end)/count(*) fail from sc
group by cno order by avg(score),fail desc;
-- 5.查询于1981年来公司所有员工的总收入(SAL和COMM):(假设没有人离职也没有新人,并且每个人的工资稳定不变)
select sum(sal) from
(select sum((sal+nvl(comm,0))*(12-extract(month from hiredate)+1)) sal from emp e
union all
select sum((sal+nvl(comm,0))*12*(extract(year from sysdate)-extract(year from hiredate))) from emp e)
;
select sum(t1.sal+t2.sal) from (
select empno,(sal+nvl(comm,0))*(12-extract(month from hiredate)+1) sal from emp order by empno) t1
join
(select empno,(sal+nvl(comm,0))*12*(extract(year from sysdate)-extract(year from hiredate)) sal from emp order by empno) t2
on t1.empno = t2.empno;
-- 6.查找字符串‘10,A,B,c,#’中逗号‘,’出现的次数:
select length('10,A,B,c,#') - length(replace('10,A,B,c,#',',','')) from dual;
-- 7.查询累计当月,到日的订单量:
-- 电脑订单表
-- 日期---下单量
-- 2.1----310
-- 2.2----590
-- 2.3----230
-- 2.4----70
-- 2.5----460
-- 2.6----90
-- 2.7----550
-- 2.8----100
-- 2.9---50
-- 实现累加(利用开窗聚合函数或者表连接)
select f.dates,sum(amount)over(order by f.dates) amount from f23 f;
-- 8.查询出从第一条记录开始到第几条记录的累计金额刚好超过100?
select * from f224;
select numb,jine,rownum from
(select f.numb,sum(f.jine)over(order by f.numb) jine from f224 f)
where jine > 100 and rownum = 1;
-- 9.根据'VIKI','GLEN','ROBIN','NICK','TOTAL'的顺序进行排序(自定义排序):
select * from (
select 'NICK' as item,12 age from dual
union all
select 'VIKI',8 from dual
union all
select 'GLEN',25 from dual
union all
select 'ROBIN',30 from dual
union all
select 'TOTAL',60 from dual
) p order by decode(p.item,'VIKI',1,'GLEN',2,'ROBIN',3,'NICK',4,'TOTAL',5)
-- 10
select * from f801;
with t as
(select to_char(f.日期,'yyyy-MM') 日期,decode(f.类型,'借款',f.金额,0) 借款金额,
decode(f.类型,'还款',f.金额,0) 还款金额 from f801 f)
select tt.日期,tt.借款金额,tt.还款金额,sum(tt.借款金额)over(order by tt.日期) 累计借款,
sum(tt.还款金额)over(order by tt.日期) 累计还款 from
(select distinct t.日期,sum(t.借款金额)over(partition by t.日期 ) 借款金额,
sum(t.还款金额)over(partition by t.日期) 还款金额
from t )tt;
select * from f801;
select t.日期,t.借款金额,t.还款金额,
sum(t.借款金额)over(order by t.日期) 累计借款,
sum(t.还款金额)over(order by t.日期) 累计还款
from
(select to_char(f.日期,'yyyy-MM') 日期,
sum(decode(f.类型,'借款',f.金额,0)) 借款金额,
sum(decode(f.类型,'还款',f.金额,0)) 还款金额
from f801 f group by to_char(f.日期,'yyyy-MM')) t
select t.月份,t.借款 as 借款金额, t.还款 as 还款金额,
sum(t.借款)over(order by t.月份) as 累计借款,
sum(t.还款)over(order by t.月份) as 累计还款
from(
select to_char(f.日期,'yyyy-MM') as 月份,
sum(decode(f.类型,'借款',f.金额,0)) 借款,
sum(decode(f.类型,'还款',f.金额,0)) 还款
from F801 f group by to_char(f.日期,'yyyy-MM')) t group by t.月份,t.借款,t.还款;
--11.
select * from f16;
select distinct t."date",sum(t.新客人数)over(partition by t."date" order by 新客人数) 新客人数,
sum(t.旧客人数)over(partition by t."date" order by 旧客人数) 旧客人数
from(select to_char(xd_time,'yyyy-MM-dd') as "date",decode(times,1,1,0) 新客人数,
case when times>1 then 1 else 0 end 旧客人数
from(select xd_time,user_name,row_number()over(partition by user_name order by xd_time) times from f16 ) )t order by t."date";
---------------------------------------------------------------------------------------
/*CREATE TABLE F880(
user_id number,
times date
);
INSERT INTO F880 VALUES (1,to_date('2021-12-07 21:13:07','yyyy_mm_dd hh24:mi:ss'));
INSERT INTO F880 VALUES (1,to_date('2021-12-07 21:15:26','yyyy_mm_dd hh24:mi:ss'));
INSERT INTO F880 VALUES (1,to_date('2021-12-07 21:17:44','yyyy_mm_dd hh24:mi:ss'));
INSERT INTO F880 VALUES (2,to_date('2021-12-13 21:14:06','yyyy_mm_dd hh24:mi:ss'));
INSERT INTO F880 VALUES (2,to_date('2021-12-13 21:18:19','yyyy_mm_dd hh24:mi:ss'));
INSERT INTO F880 VALUES (2,to_date('2021-12-13 21:20:36','yyyy_mm_dd hh24:mi:ss'));
INSERT INTO F880 VALUES (3,to_date('2021-12-21 21:16:51','yyyy_mm_dd hh24:mi:ss'));
INSERT INTO F880 VALUES (4,to_date('2021-12-16 22:22:08','yyyy_mm_dd hh24:mi:ss'));
INSERT INTO F880 VALUES (4,to_date('2021-12-02 21:17:22','yyyy_mm_dd hh24:mi:ss'));
INSERT INTO F880 VALUES (4,to_date('2021-12-30 15:15:44','yyyy_mm_dd hh24:mi:ss'));
INSERT INTO F880 VALUES (4,to_date('2021-12-30 15:17:57','yyyy_mm_dd hh24:mi:ss'));*/
select * from f880;
-- 求每个用户相邻两次浏览时间之差小于三分钟的次数:
select distinct f1.user_id,decode(f2.cnt,null,'0',f2.cnt) cnt
from f880 f1 left join
(select b.user_id,count(*) cnt from
(with t as (select f.user_id,f.times,(f.times-3/(24*60)) a,
row_number()over(partition by f.user_id order by f.times ) r
from f880 f)
select t1.user_id,t1.times,t2.a from t t1
left join t t2 on t1.r + 1 = t2.r
where t2.a < t1.times and t1.user_id = t2.user_id) b
group by b.user_id) f2 on f1.user_id = f2.user_id
order by f1.user_id ;
-- 使用偏移开窗函数
select t.user_id,sum(case when t.times>t.lead_times-3/(24*60) then 1 else 0 end) cnt from
(select f.*,lead(f.times,1,f.times+1)over(partition by f.user_id order by f.times) lead_times from f880 f) t
group by t.user_id;
-----------------------------------------------QTingLJQ------------------------------------------------
--求每个用户相邻两次浏览时间之差小于三分钟的次数:
with def_f as
(select f.*,row_number()over(partition by user_id order by times) r
from F880 f)
select ff.user_id,sum(a) 次数 from
(select f1.user_id user_id,f1.times,f2.times,(f1.times-f2.times)*24*60,
case when (f1.times-f2.times)*24*60<3 then 1 else 0 end a
from def_f f1 join def_f f2
on f1.user_id=f2.user_id and f1.r=f2.r+1) ff
group by ff.user_id;
-----------------------------------------------QTingXLJ------------------------------------------------
--求每个用户相邻两次浏览时间之差小于三分钟的次数:
-- lead()over():偏移函数
select user_id,sum(case when t1<((1/24)/60)*3 then 1 else 0 end) sum1 from
(select user_id,times,lead1-times t1 from
(select user_id,times,lead(times,1,times+1)over(partition by user_id order by times) lead1
from f880))
group by user_id;