SQL 替代递归 CTE

SQL replacement for Recursive CTE

我有一个 table 测试,其中包含

TEST
----
tablename|columnvalue|rankofcolumn
A|C1|1
A|C2|2
A|C3|3
A|C4|4
B|CX1|1
B|CX2|2
C|CY1|1
C|CY2|2
C|CY3|3

我想生成路径和其他列如下

RESULT
----
tablename|columnvalue|rankofcolumn|path
A|C1|1|C1
A|C2|2|C1->C2
A|C3|3|C1->C2->C3
A|C4|4|C1->C2->C3->C4
B|CX1|1|CX1
B|CX2|2|CX1->CX2
C|CY1|1|CY1
C|CY2|2|CY1->CY2
C|CY3|3|CY1->CY2->CY3

根据这个,我可以使用递归 CTE 来实现这个

WITH r ( tablename, columnvalue, rankofcolumn, PATH ) AS
         (SELECT    tablename,
                    columnvalue,
                    rankofcolumn,
                    columnvalue
          FROM      test
          WHERE     rankofcolumn = 1
          UNION ALL
          SELECT    xx.tablename,
                    xx.columnvalue,
                    xx.rankofcolumn,
                    r.PATH || '->' || xx.columnvalue
          FROM      r
                    JOIN test xx
                        ON     xx.tablename = r.tablename
                           AND xx.rankofcolumn = r.rankofcolumn + 1)
SELECT    *
FROM      r;

但我使用的是目前缺少此选项的 WX2 数据库。是否有 SQL 替代方案?

您可以使用逐渐填充的 table 进行强力方法。假设您的 test table 看起来像:

create table test (tablename varchar2(9), columnvalue varchar2(11), rankofcolumn number);

然后 result table 可以创建为:

create table result (tablename varchar2(9), columnvalue varchar2(11), rankofcolumn number,
  path varchar2(50));

然后为最低排名创建结果条目:

insert into result (tablename, columnvalue, rankofcolumn, path)
select t.tablename, t.columnvalue, t.rankofcolumn, t.columnvalue
from test t
where t.rankofcolumn = 1;

3 rows inserted.

并重复添加基于现有最高排名的行,从 test table 中获取以下值(如果有 tablename):

insert into result (tablename, columnvalue, rankofcolumn, path)
select t.tablename, t.columnvalue, t.rankofcolumn,
  concat(concat(r.path, '->'), t.columnvalue)
from test t
join result r
on r.tablename = t.tablename
and r.rankofcolumn = t.rankofcolumn - 1
where t.rankofcolumn = 2;

3 rows inserted.

insert into result (tablename, columnvalue, rankofcolumn, path)
select t.tablename, t.columnvalue, t.rankofcolumn,
  concat(concat(r.path, '->'), t.columnvalue)
from test t
join result r
on r.tablename = t.tablename
and r.rankofcolumn = t.rankofcolumn - 1
where t.rankofcolumn = 3;

2 rows inserted.

insert into result (tablename, columnvalue, rankofcolumn, path)
select t.tablename, t.columnvalue, t.rankofcolumn,
  concat(concat(r.path, '->'), t.columnvalue)
from test t
join result r
on r.tablename = t.tablename
and r.rankofcolumn = t.rankofcolumn - 1
where t.rankofcolumn = 4;

1 row inserted.

并继续争取最大可能的列数(即任何 table 的最高 rankofcolumn)。您可以在 WX2 中按程序执行此操作,迭代直到插入零行;但你让它听起来很有限。

经过所有这些迭代后,table 现在包含:

select * from result
order by tablename, rankofcolumn;

TABLENAME COLUMNVALUE RANKOFCOLUMN PATH                                             
--------- ----------- ------------ --------------------------------------------------
A         C1                     1 C1                                                
A         C2                     2 C1->C2                                            
A         C3                     3 C1->C2->C3                                        
A         C4                     4 C1->C2->C3->C4                                    
B         CX1                    1 CX1                                               
B         CX2                    2 CX1->CX2                                          
C         CY1                    1 CY1                                               
C         CY2                    2 CY1->CY2                                          
C         CY3                    3 CY1->CY2->CY3                                     

在 Oracle 中进行了测试,但试图避免任何特定于 Oracle 的内容;当然可能需要针对 WX2 进行调整。