oracle 递归应用(挺复杂的)
最近做数据过滤觉得很有必要记录下整个过程,说不定下次就不知道了。
废话不多说开始:
表结构:
企业表(自关联,采用树的形式记录分子公司)
区域表(自关联,采用树的形式记录省/市/县/乡,数据量大)
公司管辖区域表(公司-区域的映射表,一对多,记录了公司所具有的管辖区域)
场景:根据自己的管辖区域构建区域查询条件

分子公司都有可能维护了管辖区域,上级具有下级的管辖权限(原因:上级公司有可能没有维护下级公司具有的管辖区域,而上级公司要管理下级就不需具有下级的管辖区域,所用需同时把下级的管辖区域给上级公司一次类推),在地址维护时,维护到任何级别都具有其下级区域的管辖(比如:某个公司维护了成都,它就具有成都和成都下的全部区域的管辖权限),维护到任何级别都具有该区域上级权限(比如:某个公司维护了成都/武侯区,那它就具有武侯区,成都,四川三个权限)
说到这是不是已经晕了,(拿到公司的管辖区域进行一次向上递归和一次向下递归然后合并结果集)
第一步:递归出子公司 (4319 是总部的id)
sql:SELECT *
FROM C_COMPANY
START WITH corp_id =4319
CONNECT BY prior corp_id= corp_parentid
结果:
第二步:拿出子公司的管辖区域 c_dealers_zone 管辖区域表1,c_store_zone 管辖区域表2
sql:SELECT zid
FROM
( SELECT d.c_z_id AS zid ,d.c_com_id AS comid FROM c_dealers_zone d
UNION
SELECT s.csz_zid AS zid ,s.csz_sid AS comid FROM c_store_zone s
)
WHERE comid IN
(SELECT corp_id
FROM C_COMPANY
START WITH corp_id =4319
CONNECT BY prior corp_id= corp_parentid
)
结果:
表示4319和其下级公司已维护了的管辖区域。
第三步 将管辖区域id关联到区域信息表已拿出详细信息,并同时向上递归拿出上级(以便检索出下级)
sql:SELECT DISTINCT *
FROM c_zone
START WITH zone_id IN
(SELECT zid
FROM
( SELECT d.c_z_id AS zid ,d.c_com_id AS comid FROM c_dealers_zone d
UNION
SELECT s.csz_zid AS zid ,s.csz_sid AS comid FROM c_store_zone s
)
WHERE comid IN
(SELECT corp_id
FROM C_COMPANY
START WITH corp_id =4319
CONNECT BY prior corp_id= corp_parentid
)
)
CONNECT BY zone_id=prior zone_parent
结果:
去重前:
第四步 将管辖区域向下递归(维护到某个区域表示具有该区域下级管辖)
sql:SELECT *
FROM c_zone
START WITH zone_id IN
(SELECT zid
FROM
( SELECT d.c_z_id AS zid ,d.c_com_id AS comid FROM c_dealers_zone d
UNION
SELECT s.csz_zid AS zid ,s.csz_sid AS comid FROM c_store_zone s
)
WHERE comid IN
(SELECT corp_id
FROM C_COMPANY
START WITH corp_id =4319
CONNECT BY prior corp_id= corp_parentid
)
)
CONNECT BY prior zone_id=zone_parent
结果:
(维护到永州市就具有永州市的子集全部管辖)
第五步,将向上递归和向下递归合并结果集作为总部的管辖区域 ,加上where条件查询指定区域下的直接子集,0:中国
sql:SELECT *
FROM
(SELECT * from
(SELECT *
FROM c_zone
START WITH zone_id IN
(SELECT zid
FROM
( SELECT d.c_z_id AS zid ,d.c_com_id AS comid FROM c_dealers_zone d
UNION
SELECT s.csz_zid AS zid ,s.csz_sid AS comid FROM c_store_zone s
)
WHERE comid IN
(SELECT corp_id
FROM C_COMPANY
START WITH corp_id =4441
CONNECT BY prior corp_id= corp_parentid
)
)
CONNECT BY prior zone_id=zone_parent
)
UNION
( SELECT *
FROM c_zone
START WITH zone_id IN
(SELECT zid
FROM
( SELECT d.c_z_id AS zid ,d.c_com_id AS comid FROM c_dealers_zone d
UNION
SELECT s.csz_zid AS zid ,s.csz_sid AS comid FROM c_store_zone s
)
WHERE comid IN
(SELECT corp_id
FROM C_COMPANY
START WITH corp_id =4319
CONNECT BY prior corp_id= corp_parentid
)
)
CONNECT BY zone_id=prior zone_parent
)
)
WHERE zone_parent=0
结果:不加WHERE zone_parent=0:
加WHERE zone_parent=0(只拿出省份):
整个运行也只需要100多毫米挺快的
至此已经完成区域条件构建只拿出自己所具有的区域
总结:做完感觉数据库设计的重要性。一个好的数据库设计能够使整个开发变得简单清晰,一个糟糕的数据设计完全有可能使得某个需求无法满足。
oracle 递归查询(start with …… connect by prior ……)的灵活使用 以及 union (去重) 合并结果集
oracle 递归应用(挺复杂的)的更多相关文章
- Oracle 递归的写法(start with) 以及where条件作用域
先转一个讲Oracle递归讲得非常透彻的文章: http://blog.csdn.net/weiwenhp/article/details/8218091 前言:嗯,这也是一个前人挖坑,后人来填的故事 ...
- oracle 递归和connect by【转】
oracle递归查询(单表包含多级上下级关系) http://www.cnblogs.com/walk-the-Line/p/4882866.html -- 查找所有第一层(包括)下的所有子节点 -- ...
- oracle递归层级查询 start with connect by prior
递归层级查询:start with connect by prior 以部门表作为解析 表结构:dept{id:'主键',name:'部门名称',parent_id:'父亲id'} select * ...
- Oracle 递归
当对象存在父节点.子节点时,通过特定的方式获取父节点.子节点数据构建树状结构或其它形式结构时,通常都会使用递归,如:一个公司有多个部门.每个部门下可能有多个小部门,小部门下面又有组-.为了数据容易 ...
- Oracle递归sql笔记
查询一个机构下所辖机构: select * from t00_organ t start with t.organkey=#uporgankey# connect by prior t.organke ...
- Oracle递归 start with...connect by...prior
prior一侧是父节点 另一侧是子节点 --查询region_id等于4519的节点下面的所有子节点 查找出给定节点的所有子节点 SELECT sr.* FROM spc_region sr wher ...
- Oracle递归操作
需求:找出代理商中没有挂商家的代理商 简单SQL如下: select * from t_proxy tp where tp.id not in (SELECT tp.id as p_id FROM t ...
- [oracle] 递归追溯完整部门名称 函数
create or replace function fn_DeptWholeName2(objectid in number) return nvarchar2 is wholename nvarc ...
- oracle 分页(rownum的理解) 以及 树节点的查询
1:什么是rownum, rownum的生成, rownum相关的符号操作 Rownum是oracle生成结果集时得到的一个伪列, 按照读出行的顺序, 第一条rownum=1, 第二条=2. 对于 O ...
随机推荐
- ionic 中$ionicView.beforeEnter 事件的一个bug
我在使用ionic写app的时候,需要使用$IonicView.beforeEnter事件,在页面进入前做一些事情,但是发现,它不起作用,很蛋疼,后来,看了别人做的app例子,也涉及到这个$Ionic ...
- 一步一步安装UEFI分区方式的windows 10 企业版
发现很多坛友不会安装UEFI分区的windows 10 从启动设置,到分区,到最后的引导与激活都是很大的问题. 在我看来这是最不容易出错的安装方式适合于刚刚上手的菜鸟,自己按照图片一步一步的就可以安装 ...
- 读《编写可维护的JavaScript》第六章总结
第六章 避免使用全局变量 JavaScript执行环境在很多方面都有其独特之处,全局变量就是其中之一.“全局变量”是一个神秘的对象,它表示了脚本的最外层上下文. 在浏览器中,windows对象往往重载 ...
- 使用jquery实现搜索框的位置变换
现在很多的网站都存在这样一个效果:当用户搜索信息后,滚动内容时,搜索框的位置会产生变化,会固定在某个位置,方便用户进行再次搜索.比如百度图片.为了提高系统用户体验,也想加入这个效果,经过小段时间摸索, ...
- gif图片加载问题
之前从没想过,gif图片在网页中显示还会有问题,不过今天算是遇到了bug,问题是在vc嵌入的网页里面,有三个需要显示加载的动态图,刚开始在html中写好,在div向上滚动显示gif的时候就成了静态的. ...
- 实验二 用C语言表示进程的调度
实验二 一. 实验目的 通过模拟进程的调度,进一步了解进程的调度的具体过程. 二. 实验内容和要求 1.进程PCB的结构体定义 2.定义队列 3.输入进程序列 4.排序(按到位时间) 5.输出进程运行 ...
- TestNG Study Note 1 - Eclipse 插件安装
TestNG 插件在线安装 Help -> Install New Software -> Add -> Paste TestNG url to Add: http://testn ...
- Android 异步消息处理机制
1.Handler的由来 当程序第一次启动的时候,Android会同时启动一条主线程( Main Thread)来负责处理与UI相关的事件,我们叫做UI线程. Android的UI操作并不是线程安全的 ...
- Android 四大组件之四(ContentProvider)
ContentProvider调用关系: ContentProvider(数据提供者)是应用程序之间共享数据的一种接口机制,是一种更为高级的数据共享方法. ContentProvider可以指定需要共 ...
- centos 更新linux内核
之前一直使用centos 7系统进行开发,centos 7.0 系统自带的linux内核版本为 linx 3.10,最近开发需要使用到socket的reuse port特性,该特性在linux 3.9 ...