我有一个输入数据,其中包含 ID、上一个、当前和下一个节点(未排序)。我必须在每个 ID 的第一页和最后一页之间找到一条路径,该路径涵盖了遍历的所有节点。例如:如果我的输入数据是这样的:第一列是 ID,第二列是 prev_node,第三列是当前节点,第四列是下一个节点。Prev_node 将是空的起始值,下一个节点将是空的最后一个值
输入
id 上一个 当前下一个 1个ABC 1个 1个 1个 1 bcd 1 bgh 1 个 1 光盘 1 cbg 1代 1个 1 效 1个 1个 1个 1 个晶圆厂 1吉 1 个 1个 1 伊吉 1个 1 公斤 1个 1 公里 1 分钟 1个lna 1 mna 1个 1个操作 1 份 1 qrs 第一个 1个 1 台 1 紫外线 1个 1个 1个抗体
输出应该是当前节点的路径,例如 -
识别电流 1个 1个 1摄氏度 1天 1个 1e 1 英尺 1e 1 英尺 1 英尺 1 英尺 1个 1个 1个 1克 1小时 1 我 1j 1j 1 我 1 我 1千 1升 1米 1个 1个 1个 1个 1个 1个 1个 1r 1 秒 1吨 1个 1 伏 1 瓦 1 个
这里会有许多具有相似数据的 ID,我只显示了一个 ID(1)。同样在这里,我使用了实际上是 200-500 个字符长的字符串的字母。我尝试了几乎没有修改的 SQL 方法,如果 ID 的行数为 100 或以下,但它会为更多行提供字符串连接错误(即使在将长字符串转换为数字之后)。任何人都可以建议一种基于稳健程序的方法。我尝试了一些,但它不适用于超过 300 行的 ID。
我有时遇到以下代码的错误是“字符串连接的结果太长”
我的代码
create or replace procedure pathing
as
type varr is table of varchar(4000);
visit varr;
t number;
--v varchar2(40);
fp varchar2(1000);
np varchar2(1000);
type stype is record(fp varchar2(1000),np varchar2(1000),t number);
type sinput is table of stype;
iarray sinput;
begin
select id
bulk collect into visit
from table_source
group by id
order by count(1) desc;
delete from table_final;
commit;
for k in visit.first .. visit.last loop
delete from table_temp;
commit;
insert into table_temp
select distinct prev_pg, page_id, next_pg, visit(k)
from table_source
where visit_id = visit(k)
order by prev_pg desc;
commit;
insert into table_final
WITH t_n AS (
SELECT prev_pg, page_id, next_pg, rownum n FROM table_temp
),
t_br AS (
SELECT
prev_pg,
page_id,
'<' || listagg(n, '|<') within GROUP(ORDER BY n) || '|' br,
COUNT(0) cnt
FROM
t_n
GROUP BY
prev_pg, page_id
),
t_mp AS (
SELECT
'|' || listagg(list) within GROUP(ORDER BY NULL) list
FROM (
SELECT REPLACE(br, '<') list FROM t_br WHERE cnt > 1
)
),
t_path(step, page_id, next_pg, used) AS (
SELECT 1, page_id, next_pg, ''
FROM t_n
WHERE prev_pg is null
UNION ALL
SELECT
step + 1,
t_br.page_id,
t_n.next_pg,
CASE
WHEN instr(list, '|' || n || '|') = 0
THEN used
ELSE used || n || '|'
END
FROM
t_mp,
t_path
JOIN t_br
ON next_pg = t_br.page_id AND t_path.page_id = prev_pg
JOIN t_n
ON n = regexp_substr(br, '^(<(' || used || '0)\|)*(<(\d+))?', 1, 1, '', 4)
) cycle step
SET is_cycle TO 'Y' DEFAULT 'N'
SELECT
page_id,
next_pg,
step,
visit(k)
FROM t_path
ORDER BY 1;
commit;
end loop;
end;
进一步解释我的示例:-我想要每个 ID 的完整路径旅程,在示例中我以 ID 1 为例。对于 ID 1,我们有一组当前、上一个和下一个值。所以我们需要使用这些值找到路径。例如,对于 id 1,路径以“a”开头,因为 prev 列是空的。然后我们看到 a 的下一个值是 b 即当前是 a 并且下一个是 b 所以我们在 id 1 的所有行中搜索上一个值作为 a 和当前值作为 b ,在这一点上我们找到相同的我们取下一个行的值并重复该过程。例如这里 prev a ,current b 和 next 是 c 所以我们再次搜索 prev b 和 current c 等等,直到我们得到完整路径,直到我们遇到 next as null 因为那将是最后一个