动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > 数据库 > Oracle教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
数据库:数据库教程,数据库技巧,Oracle教程,MySQL教程,Sybase教程,Access教程,DB2教程,数据库安全,数据库文摘
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ Oracle教程 ]的信息

本月文章推荐
.Oracle9i初始化参数中文说明(16).
.Oracle索引原理.
.WIN2000域模式和WIN2003+ORA816不.
.配置Windows与Linux平台的DATA G.
.ExactPapers Oracle 1Z0-007 200.
.提高查询主、从表速度的一个方法.
.怎样保持Oracle数据优良性能的若.
.使用脚本和查询来主动监视Oracle.
.Oracle高级安全性.
.ORACLE 9I FOR AIX 5L 的安装.
.从MySQL中导出XLS数据库工具.
.如何学习Oracle9i认证专员(OCA).
.Oracle:PL/SQL中怎样使用Array.
.在Oracle中实现搜索分页查询.
.导入数据后编译所有对象的脚本.
.一个病入膏肓的数据库优化.
.在Oracle中实现数字进制转换完全.
.利用Oracle的同意安全机制来控制.
.UNIX平台上分布式数据库管理的经.
.Oracle-Decode()函数和CASE语句有.

Oracle层次查询和分析应用在号段选取

发表日期:2008-2-9 |


  1. 问题的提出   在实际工作中,我们经常会碰到号段选取的问题,例如:一组连续的数,去掉中间一些数,要求出剩下的数的区间(即号段)   例如:一串数字为1,2,3,4,7,9,10,则号段为1-4,7-7,9-10   知道号段的起止,要求出该号段内所有的数   例如:号段为1-3,15-15,则号段内所有的数为1,2,3,15   一组数,中间可能有断点,要求出缺失的数   例如:一串数字为1,2,3,4,7,9,10,则缺失的数为5,6,8   已知大号段范围及已用号段范围,求可用号段范围   例如:大号段范围0-999,已用号段范围0-200,399-599,则可用号段范围为201-398,600-999   2. 基础知识   先做下热身运动,回顾一下层次查询和lead/lag函数的运用。   2.1 伪列rownum和level   伪列就是并非在表中真正存在的列。已有很多资料介绍rownum和level这两个伪列。这里只想强调一点,伪列是只针对结果集的。   2.2 利用层次查询构造连续的数   产生5~8这4个连续的数   select * from (select rownum+4 from dual connect by rownum<5);   select * from (select level+4 from dual connect by level<5);   以8月为界,例如2005年8月1日,之前的在校学生入学年份为2001~2004,之后的为2002~2005.求当前日期下的在校学生入学年份:   select * from (select to_char(add_months(sysdate, 4), 'yyyy') - rownum from dual connect by rownum<5);   2.3 用分析函数Lead和Lag获得相邻行的字段值 select rn, lag(rn)over(order by rn) previos, lead(rn)over(order by rn) next from (select rownum+4 rn from dual connect by rownum<5);

RN PREVIOS NEXT
---------- ---------- ----------
5 6
6 5 7
7 6 8
8 7   简单的说,在这里,Lag是获得前一行的内容,而Lead是获得后一行的内容。 select rn, lag(rn,2,-1)over(order by rn) previos, lead(rn,2,-1) over(order by rn) next from (select rownum+4 rn from dual connect by rownum<5);

RN PREVIOS NEXT
---------- ---------- ----------
5 -1 7
6 -1 8
7 5 -1
8 6 -1   这里,通过指定offset参数来获得两行前的内容和两行后的内容,假如offset超出范围并且未设定默认值-1,那么系统会自动将其值设为NULL.     3. 问题的解决   有了基础知识的积累,我们就可以解决前面提到的问题。   3.1 已知号码求号段   3.1.1 题例   我有一个表结构, fphm,kshm
2014,00000001
2014,00000002
2014,00000003
2014,00000004
2014,00000005
2014,00000007
2014,00000008
2014,00000009
2013,00000120
2013,00000121
2013,00000122
2013,00000124
2013,00000125   (第二个字段内可能是连续的数据,可能存在断点。)   怎样能查询出来这样的结果,查询出连续的记录来。   就像下面的这样? 2014,00000001,00000005
2014,00000009,00000007
2013,00000120,00000122
2013,00000124,00000125   3.1.2 解答   思路:利用lead取得下一行的kshm,然后和本行的kshm想比,假如差值为1,说明这一行和下一行是连续的。由于首尾的非凡性,故而需要先用max和min来获得首尾点。 select fphm, nvl(lag(e)over(partition by fphm order by s),minn) ST, nvl(S,maxn) EN from
(select fphm, lag(kshm,1) over(partition by fphm order by kshm) S, kshm E, min(kshm)over(partition by fphm) minn, max(kshm) over(partition by fphm) maxn from t)
where nvl(E-S-1,1)<>0;

FPHM ST EN
---------- ---------- ----------
2013 00000120 00000122
2013 00000124 00000125
2014 00000001 00000005
2014 00000007 00000009
  3.2 根据号段求出包含的数   3.2.1 题例   有表及测试数据如下: CREATE TABLE T20
(
ID NUMBER(2),
S NUMBER(5),
E NUMBER(5)
);

INSERT INTO T20 ( ID, S, E ) VALUES ( 1, 10, 11);
INSERT INTO T20 ( ID, S, E ) VALUES ( 2, 1, 5);
INSERT INTO T20 ( ID, S, E ) VALUES ( 3, 88, 92);
COMMIT;   S为号段起点,E为号段终点,求出起点和终点之间的数(包括起点和终点)   3.2.2 解答   很明显,这需要构造序列来解决问题 select a.id, a.s, a.e,b.dis, a.S+b.dis-1 h from
t20 a,
(select rownum dis from
(select max(e-s)+1 gap from t20)
connect by rownum<=gap) b
where a.e>=a.s+b.dis-1
order by a.id, 4   运行结果: ID S E DIS H
---------- ---------- ---------- ---------- ----------
1 10 11 1 10
1 10 11 2 11
2 1 5 1 1
2 1 5 2 2
2 1 5 3 3
2 1 5 4 4
2 1 5 5 5
3 88 92 1 88
3 88 92 2 89
3 88 92 3 90
3 88 92 4 91
3 88 92 5 92   我们再看下面这种做法: select a.id, a.s, a.e,rownum, a.S+rownum-1 h from
t20 a ,
(select id, e-s+1 gap from t20 where id=2) b
where a.id=b.id
connect by rownum<=gap

ID S E ROWNUM H
---------- ---------- ---------- ---------- ----------
2 1 5 1 1
2 1 5 2 2
2 1 5 3 3
2 1 5 4 4
2 1 5 5 5   嗯,得到的结果也是正确的,若我们把粗斜体字部分去掉后,看看结果是什么样: ID S E ROWNUM H
---------- ---------- ---------- ---------- ----------
1 10 11 1 10
1 10 11 2 11
2 1 5 3 3
2 1 5 4 4
2 1 5 5 5
2 1 5 6 6
3 88 92 7 94   这样的结果,显然不是我们需要的,更何况,这是错误的。由此更能深入理解,伪列是只针对结果集的。   3.3 求缺失的号3.3.1 题例table T,列:serial_no我想能够查询一下serial_no这个字段的不连续的值。   例如: serial_no
1
2
3
4
6
8
9
10   我想一个sql语句查出来缺失的号码   显示结果为: 5
7   3.3.2 解答思路:找出数B和它前面的数A进行比较(数按从大到小进行排序),假如B-A=1,则说明是连续的,中间没有断点。 select distinct s+level-1 rlt from (select lag(serial_no,1) over(order by serial_no)+1 S, serial_no-1 E from t) where E-S<>0 connect by level<=e-s  3.4 求尚未使用的号段 3.4.1 题例 表A结构: bill_type_id varchar2(1),
bill_start number,
bill_end number,
Office_level varchar2(4)   数据如下: A 0 999 1
A 0 199 2
A 300 499 2
A 700 799 2  sql目的是取出包含在level1级别里的,还没有录入level2级别的号段。   3.4.2 解答这个似乎是3.1和3.3这两个问题的逆问题创建表及测试数据: CREATE TABLE T8
(
A NUMBER(4),
B NUMBER(4),
C NUMBER(4),
Q VARCHAR2(1 BYTE)
);

Insert into T8(A, B, C, Q)Values(555, 666, 2, 'A');
Insert into T8(A, B, C, Q)Values(100, 199, 2, 'A');
Insert into T8(A, B, C, Q)Values(0, 999, 1, 'A');
Insert into T8(A, B, C, Q)Values(300, 499, 2, 'A');
COMMIT;
  思路:将大号段的边界与小号段的边界相比,从大号段中将小号段“挖”掉,这样剩下的就是可用号段了。 select S,E from
(
SELECT NVL2(LAG(A)OVER(PARTITION BY Q ORDER BY A), B+1, MIN(A)OVER(PARTITION BY Q)) S,
NVL(LEAD(A)OVER(PARTITION BY Q ORDER BY A)-1, MAX(B)OVER(PARTITION BY Q)) E
from t8 START WITH C=1 CONNECT BY C-1 = PRIOR C AND Q= PRIOR Q
)
where s<=e   运行结果: S E
---------- ----------
0 99
200 299
500 554
667 999   参考资料   Oracle 8i SQL Reference   http://lastwinner.itpub.net   http://hsmxxyy.itpub.net/   论坛相关讨论帖子   请教查询语句的写法? http://www.itpub.net/435578.Html   如何sql查询出连续号码段 http://www.itpub.net/354052.html   请教关于号段选取的sql写法 http://www.itpub.net/480536.html   知道号段起止,如何选择该号段内的所有号码? http://www.itpub.net/701508.html
上一篇:Oracle诊断工具-RDA使用概述 人气:919
下一篇:用Oracle的异构服务连接异种数据源 人气:459
浏览全部Oracle教程的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-8-30 HBcms(宏博cms)内容管理系统 v1.1
2008-8-30 邓西网站帮助系统 v2.3
2008-8-30 破竹CMS v4.0.7.21
2008-8-30 美女写真网图片小偷 v1.5 全站静
2008-8-30 PHP美女写真Cms v1.00
2008-8-30 PHPer.yang情书系统 v1.0
2008-8-30 快乐商城全站源码
2008-8-29 oblog v4.6 build 20080827
2008-8-29 ASBLOG v2.5 bulid 080828
2008-8-23 Mini WinMount V0.4
2008-8-23 Vista优化大师3.11正式版
2008-8-23 Wine 1.13
2008-8-23 KlipFolio 5.0 Build 5899-80
2008-8-23 Windows Sysinternals Desktops
2008-8-23 OneTap Movies1.2破解版
2008-8-23 AnnotaterPDF阅读1.1.503 破解版
2008-8-23 SoundMeter分贝测量仪 v1.0汉化破
2008-8-23 iDrum音乐节拍1.0破解版
  发表评论
姓 名: 验证码:
内 容:
站长工具:网站收录查询 | Google PR查询 | ALEXA排名查询 | CSS在线编辑器 | 广告代码 | Html转换js | js/vbs加密 | md5加密 | 进制转换
实用工具:汉字翻译拼音 | 符号对照表 | 个税计算 | 经典小工具 | 汉字简繁转换 | 普通单位换算 | 公制单位换算 | 生辰老黄历 | 国内电话区号 国家代码与域名缩写 | 文字加密解密 | 健康查询 | 万年历 | 汉字横竖排版 | 手机号码查询 | 计算器 | ip搜索
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報
防水工事·改修工事 フットサル大会 探偵