方案2.不利用pro_code列 但效率比上一个方案低 select b.xm_code,b.xm_name,a.pro_code,a.pro_name from (select AA_XM.*,rownum rn from AA_XM)a, (select AA_XM.*,rownum rn from AA_XM)b where a.rn>=b.rn and b.xm_code is not null and not exists( select 1 from (select AA_XM.*,rownum rn from AA_XM)c where xm_code is not null and rn<=a.rn and rn>b.rn)方案3.这个效率应该还不错,用树形查询来处理。如果原表中pro_code不是从小到大,或者不连续,则方案1不适用。试试这个 select connect_by_root xm_code xm_code, connect_by_root xm_name xm_name, pro_code,pro_name from( select AA_XM.*,rownum rn from AA_XM) connect by prior rn=rn-1 and xm_code is null start with xm_code is not nullXM_CODE XM_NAME PRO_CODE PRO_NAME 01 一般管理事务 01 一般管理事务 01 宣传管理 01 xx论坛 01 宣传管理 02 奖励支出 01 宣传管理 03 新闻宣传 02 宣传报道 01 媒体占用 02 宣传报道 02 网络运行 02 宣传报道 03 移动频道 03 影视制作费 01 文艺精品制作 03 影视制作费 02 专题片制作
有px的话,减少一个子查询 select connect_by_root xm_code xm_code, connect_by_root xm_name xm_name, pro_code,pro_name from AA_XM connect by prior px=px-1 and xm_code is null start with xm_code is not null
(
XM_CODE VARCHAR2(200),
XM_NAME VARCHAR2(400),
PRO_CODE VARCHAR2(200),
PRO_NAME VARCHAR2(400)
);
insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME)
values ('01', '一般管理事务', '01', '一般管理事务');insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME)
values ('01', '宣传管理', '01', 'xx论坛');insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME)
values ('', '', '02', '奖励支出');insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME)
values ('', '', '03', '新闻宣传');insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME)
values ('02', '宣传报道', '01', '媒体占用');insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME)
values ('', '', '02', '网络运行');insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME)
values ('', '', '03', '移动频道');insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME)
values ('03', '影视制作费', '01', '文艺精品制作');insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME)
values ('', '', '02', '专题片制作');
commit;
或者文字描述下吧
原表的设计很危险
原表中的记录是按数据插入顺序排列的,这也是这个查询基于的先决条件
但是实际上有可能会不按这个顺序的。应该有个主键作为标识就本例而言,语句如下
select max(xm_code)over(partition by flag)xm_code,
max(xm_name)over(partition by flag)xm_name,
pro_code,pro_name
from(select a.*,rownum-to_number(pro_code) flag from aa_xm a)XM_CODE XM_NAME PRO_CODE PRO_NAME
01 一般管理事务 01 一般管理事务
01 宣传管理 01 xx论坛
01 宣传管理 02 奖励支出
01 宣传管理 03 新闻宣传
02 宣传报道 01 媒体占用
02 宣传报道 03 移动频道
02 宣传报道 02 网络运行
03 影视制作费 01 文艺精品制作
03 影视制作费 02 专题片制作
但效率比上一个方案低
select b.xm_code,b.xm_name,a.pro_code,a.pro_name
from
(select AA_XM.*,rownum rn from AA_XM)a,
(select AA_XM.*,rownum rn from AA_XM)b
where a.rn>=b.rn
and b.xm_code is not null
and not exists(
select 1 from (select AA_XM.*,rownum rn from AA_XM)c
where xm_code is not null and rn<=a.rn
and rn>b.rn)方案3.这个效率应该还不错,用树形查询来处理。如果原表中pro_code不是从小到大,或者不连续,则方案1不适用。试试这个
select connect_by_root xm_code xm_code,
connect_by_root xm_name xm_name,
pro_code,pro_name from(
select AA_XM.*,rownum rn from AA_XM)
connect by prior rn=rn-1 and xm_code is null
start with xm_code is not nullXM_CODE XM_NAME PRO_CODE PRO_NAME
01 一般管理事务 01 一般管理事务
01 宣传管理 01 xx论坛
01 宣传管理 02 奖励支出
01 宣传管理 03 新闻宣传
02 宣传报道 01 媒体占用
02 宣传报道 02 网络运行
02 宣传报道 03 移动频道
03 影视制作费 01 文艺精品制作
03 影视制作费 02 专题片制作
create table AA_XM
(
XM_CODE VARCHAR2(200),
XM_NAME VARCHAR2(400),
PRO_CODE VARCHAR2(200),
PRO_NAME VARCHAR2(400),
PX NUMBER
);
insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME, PX)
values ('01', '一般管理事务', '01', '一般管理事务', 1);insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME, PX)
values ('01', '宣传管理', '01', 'xx论坛', 2);insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME, PX)
values ('', '', '02', '奖励支出', 3);insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME, PX)
values ('', '', '03', '新闻宣传', 4);insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME, PX)
values ('02', '宣传报道', '01', '媒体占用', 5);insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME, PX)
values ('', '', '02', '网络运行', 6);insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME, PX)
values ('', '', '03', '移动频道', 7);insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME, PX)
values ('03', '影视制作费', '01', '文艺精品制作', 8);insert into aa_xm (XM_CODE, XM_NAME, PRO_CODE, PRO_NAME, PX)
values ('', '', '02', '专题片制作', 9);
commit;
select connect_by_root xm_code xm_code,
connect_by_root xm_name xm_name,
pro_code,pro_name from AA_XM
connect by prior px=px-1 and xm_code is null
start with xm_code is not null