如何在SQL Plus中使用ROWID获取派生表结果集的ORDERED结果?

时间:2012-06-26 17:42:57

标签: sql oracle

我有一个emp表格如下

empnum deptno salary
----- ------ ------
1      null    null
null   2       null
null   null    null
null   null    3
5      null    4
null   6       1  

我希望结果集应该像

result
------
1
2
0
3
5
4
6
1

如果有3 nulls,则应显示0
如果有only one null则应显示 插入它们的顺序相同的其他两个值,
如果有'2个空值'那么它应该在结果集中显示一个值。

我试过了

select rs from  
((select decode(empno||deptno||sal,null,0,substr(empno||deptno||sal,1,1)as rs,rowid as ri from emp)
union  
((select decode(empno||deptno||sal,null,0,substr(empno||deptno||sal,2,1)as rs,rowid as ri from emp)  
minus  
(select decode(empno||deptno||sal,null,0,substr(empno||deptno||sal,1,1)as rs,rowid as ri from emp)))  
where rs is not null  
order by ri,rs;

上述查询将结果显示为

rs
--
1
2
0
3
4
5
1
6

任何人都可以帮助我获得如上所述的确切结果集。

提前致谢..

1 个答案:

答案 0 :(得分:1)

这个答案很大程度上取决于你的表格的创建方式。它需要使用ROWDEPENDENCIES创建,每次插入后都需要有一个COMMIT,以确保维护订单。

这可能对现实世界的数据没有用。如果您没有在表中存储时间戳以记录记录的插入时间,则无法确定列的顺序。

使用样本表和数据:

create table emp
(empnum int, deptno int, salary int) ROWDEPENDENCIES;
insert into emp (empnum, deptno, salary) values
(1,      null,    null); 
commit;
insert into emp (empnum, deptno, salary) values
(null,   2,       null);
commit;
insert into emp (empnum, deptno, salary) values
(null,   null  ,  null); 
commit;
insert into emp (empnum, deptno, salary) values
(null ,  null ,   3); 
commit;
insert into emp (empnum, deptno, salary) values
(5     , null,    4);
commit;
insert into emp (empnum, deptno, salary) values
(null   ,6 ,      1  ); 
commit;

create table emp2
(empnum int, deptno int, salary int, rowscn int) ROWDEPENDENCIES;
insert into emp2
select empnum, deptno, salary, ora_rowscn from emp;

然后,您可以使用ORA_ROWSCN伪列来确定插入日期:

with countqry as
(select empnum, deptno, salary, 
        rowscn,
        decode(empnum, null, 0, 1) e,
        decode(deptno, null, 0, 1) d,
        decode(salary, null, 0, 1) s    
from emp2)
select 0 as val, rowscn 
from countqry where e+d+s = 0
union  all
select coalesce(empnum, deptno, salary) as val, 
       rowscn
from countqry where e+d+s = 1
union all 
select val, rowscn from
(
select * from 
  (select empnum, deptno, salary, rowscn 
    from countqry where e+d+s >= 2)
unpivot (val for x in (empnum as '1', deptno as '2', salary as '3'))
order by rowscn, val
)
order by rowscn

Here is a working example on SQLFiddle.