oracle 每日一题-分析函数的RANGE/ROW窗口
来源:互联网 发布:linux线程详解 编辑:程序博客网 时间:2024/05/08 23:00
运行环境:SQLPLUS, SERVEROUTPUT已打开
我有一张表,登记着我在哪些日期有手机漫游(漫游的意思是我在国外)。我还有一个视图,生成了特定期间的所有日期:
create table plch_roaming (
roam_date date primary key
)
/
insert into plch_roaming values (date '2016-01-03')
/
insert into plch_roaming values (date '2016-01-04')
/
insert into plch_roaming values (date '2016-01-05')
/
insert into plch_roaming values (date '2016-01-06')
/
insert into plch_roaming values (date '2016-01-09')
/
insert into plch_roaming values (date '2016-01-10')
/
insert into plch_roaming values (date '2016-01-11')
/
insert into plch_roaming values (date '2016-01-12')
/
insert into plch_roaming values (date '2016-01-14')
/
commit
/
create view plch_calendar as
select date '2016-01-01' + level - 1 as calendar_date
from dual
connect by level <= 14
/
我的手机费是统一费率(相当于包月),当我在漫游也是如此。但仅仅是在漫游不太多的时候。 规则如下:
当我不在漫游(我在国内),通话包含在统一费率中。
当我在漫游时,如果我之前四天中漫游不多于两天,则通话仍然包含在统一费率中。
当我在漫游时,如果我之前四天中漫游多于两天,则在统一费率之上有附加费。
例如,一月份的前几天我不在漫游,那些天是统一费率的。1月3号我在漫游,但是之前的四天没有一天是在漫游,所以它仍然是统一费率。在1月4号,之前的四天中有一天漫游,所以1月4号仍然是统一费率。1月5号是统一费率,因为前四天之中有两天是在漫游。但是1月6号要收费,因为之前的四天中有三天在漫游。
对于一月份的前14天(日期由上述视图生成),我想要一个清单,每天显示我的所在地(在家(Home)或者漫游(Roaming)), 以及当天的通话是包含在统一费率(Flat)或者是要额外收费(Fee)。
哪些选项包含了一个查询能够给我这样的一个清单:
CALENDAR_D LOCATIO CHAR
---------- ------- ----
2016-01-01 Home Flat
2016-01-02 Home Flat
2016-01-03 Roaming Flat
2016-01-04 Roaming Flat
2016-01-05 Roaming Flat
2016-01-06 Roaming Fee
2016-01-07 Home Flat
2016-01-08 Home Flat
2016-01-09 Roaming Flat
2016-01-10 Roaming Flat
2016-01-11 Roaming Flat
2016-01-12 Roaming Fee
2016-01-13 Home Flat
2016-01-14 Roaming Fee
(A)
select c.calendar_date
, case
when r.roam_days is null then 'Home'
else 'Roaming'
end as location
, case
when r.roam_days > 2 then 'Fee'
else 'Flat'
end as charge
from plch_calendar c
left outer join (
select roam_date
, count(*) over (
order by roam_date
RANGE between interval '4' day preceding
and interval '1' day preceding
) as roam_days
from plch_roaming
) r
on r.roam_date = c.calendar_date
order by c.calendar_date
/
(B)
select c.calendar_date
, case
when r.roam_days is null then 'Home'
else 'Roaming'
end as location
, case
when r.roam_days > 2 then 'Fee'
else 'Flat'
end as charge
from plch_calendar c
left outer join (
select roam_date
, count(*) over (
order by roam_date
ROWS between interval '4' day preceding
and interval '1' day preceding
) as roam_days
from plch_roaming
) r
on r.roam_date = c.calendar_date
order by c.calendar_date
/
(C)
select c.calendar_date
, case
when r.roam_days is null then 'Home'
else 'Roaming'
end as location
, case
when r.roam_days > 2 then 'Fee'
else 'Flat'
end as charge
from plch_calendar c
left outer join (
select roam_date
, count(*) over (
order by roam_date
ROWS between 4 preceding and 1 preceding
) as roam_days
from plch_roaming
) r
on r.roam_date = c.calendar_date
order by c.calendar_date
/
(D)
select calendar_date
, case
when roam_date is null then 'Home'
else 'Roaming'
end as location
, case
when roam_date is not null and roam_days > 2 then 'Fee'
else 'Flat'
end as charge
from (
select c.calendar_date
, r.roam_date
, count(r.roam_date) over (
order by c.calendar_date
RANGE between interval '4' day preceding
and interval '1' day preceding
) as roam_days
from plch_calendar c
left outer join plch_roaming r
on r.roam_date = c.calendar_date
)
order by calendar_date
/
(E)
select calendar_date
, case
when roam_date is null then 'Home'
else 'Roaming'
end as location
, case
when roam_date is not null and roam_days > 2 then 'Fee'
else 'Flat'
end as charge
from (
select c.calendar_date
, r.roam_date
, count(r.roam_date) over (
order by c.calendar_date
ROWS between 4 preceding and 1 preceding
) as roam_days
from plch_calendar c
left outer join plch_roaming r
on r.roam_date = c.calendar_date
)
order by calendar_date
/
本题考查分析函数中over()用法开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化,举例如下:
over(order by salary)按照salary排序进行累计,orderby是个默认的开窗函数
over(partition by deptno)按照部门分区
over(order by salary range between 50 preceding and 150 following)
每行对应的数据窗口是之前行幅度值不超过50,之后行幅度值不超过150
over(order by salary rows between 50 preceding and 150 following)
每行对应的数据窗口是之前50行,之后150行
over(order by salary rows between unboundedpreceding and unbounded following)
每行对应的数据窗口是从第一行到最后一行,等效:
over(order by salary range between unboundedpreceding and unbounded following)
本题关键
left outer join (
select roam_date
, count(*) over (
order by roam_date
RANGE between interval '4' day preceding
and interval '1' day preceding
) as roam_days
from plch_roaming
) r
over (
order by roam_date
RANGE between interval '4' day preceding
and interval '1' day preceding
)
select c.calendar_date
, r.roam_date
, count(r.roam_date) over (
order by c.calendar_date
ROWS between 4 preceding and 1 preceding
) as roam_days
from plch_calendar c
left outer join plch_roaming r
on r.roam_date = c.calendar_date
over (
order by c.calendar_date
ROWS between 4 preceding and 1 preceding
)
答案 A D E
B:错误,数据类型不一致,rows是按物理位置排序
C:错误,因为rows是按物理位置排序,导致从第3个roam_days开始都是大于2
E:正确,进行左连接后非漫游时roam_date是空值,count(r.roam_date)不会计算空值
- oracle 每日一题-分析函数的RANGE/ROW窗口
- oracle 每日一题-分析函数row_number
- oracle分析函数:一、窗口子句的使用
- 分析函数窗口子句 RANGE/ROWS 差别
- 分析函数窗口子句 RANGE/ROWS 差别
- oracle的分析函数over及开窗关键字range
- oracle 每日一题-游标的参数
- Oracle 分析函数/窗口函数
- oracle 每日一题-分析程序的内存开销(sga,pga,uga)
- oracle 每日一题-12c新功能:json函数
- 分析函数用法及窗口子句 range/rows差别
- 分析函数用法及窗口子句 range/rows差别
- leetcode 每日一题 34. Search for a Range
- Oracle 分析函数的使用(一)
- Oracle 分析函数的使用(一)
- oracle 每日一题-可修改的视图
- Index Range Scan【每日一译】--20121221
- 每日一题(34) - 包含最小值Min函数的栈
- 上亿大表加字段
- 软件开发模式
- BGSHOOT - Shoot and kill 离散化 树状数组或前缀和 ST表 模板题
- 【基础】 Data Binding的简单使用
- 了解Linux 内存使用
- oracle 每日一题-分析函数的RANGE/ROW窗口
- fedora23 安装python3
- 第一个Struts2案例
- 第五章 Cluster和Loadbalance
- 欢迎使用CSDN-markdown编辑器
- 如何让页面回到顶部
- sh/bash/csh/Tcsh/ksh/pdksh等shell本质区别
- caffe python常用语句
- 八大排序算法