只是为了好玩,另一种 (ab) 使用递归 CTE (11gR2+) 的方法:
with
data_table (title, val_a, val_b) as (
select 'A', 1, 1 from dual union all
select 'B', 1, 2 from dual
),
tmp (title, val_a, val_b, marker, flag) as (
select d.*,
case when val_a <> val_b then 'MULTIPLE' else 'SINGLE' end,
case when val_a <> val_b then 1 else 0 end
from data_table d
union all
select title, val_a, val_b, marker, 0
from tmp
where flag = 1
)
select title, val_a, val_b, marker
from tmp
order by title, val_a, val_b;
TITLE VAL_A VAL_B MARKER
----- ---------- ---------- --------
A 1 1 SINGLE
B 1 2 MULTIPLE
B 1 2 MULTIPLE
锚成员使用 case 表达式来决定该行是单行还是多行,并设置一个标志;递归成员用来终止的。
在这种情况下,它会在一次迭代后终止,这似乎有点矫枉过正。如果需要,尽管它可以适应产生几个额外的行,例如一个代表两个值之间的差异:
with
data_table (title, val_a, val_b) as (
select 'A', 1, 1 from dual union all
select 'B', 1, 2 from dual union all
select 'C', 4, 7 from dual
),
tmp (title, val_a, val_b, marker, flag) as (
select d.*,
case when val_a <> val_b then 'MULTIPLE' else 'SINGLE' end,
abs(val_b - val_a)
from data_table d
union all
select title, val_a, val_b, marker, flag - 1
from tmp
where flag > 0
)
select title, val_a, val_b, marker
from tmp
order by title, val_a, val_b;
TITLE VAL_A VAL_B MARKER
----- ---------- ---------- --------
A 1 1 SINGLE
B 1 2 MULTIPLE
B 1 2 MULTIPLE
C 4 7 MULTIPLE
C 4 7 MULTIPLE
C 4 7 MULTIPLE
C 4 7 MULTIPLE
就像我说的,只是为了好玩,因为这不是您当前的要求 *8-)