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 进行调整。
我有一个 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
根据这个
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 进行调整。