按普通人分组递归循环
Grouping recursive cycle by common person
我是 PL/SQL 的新手,我正在努力完成我得到的任务。
我有法律实体和自然实体。每个法律实体都可以有一些自然实体,这些自然实体可以与 1 个或多个实体相关联。
- A 公司有客户#1、#2 和#3
- 公司 B 有客户 #2 和 #4
- 公司 C 有第 4 个不满
- 公司 D 有不满 #5
- 公司 E 有第 6 位客户
- F 公司有第 6 位客户
结果应显示哪些公司通过一些不一致的因素联系在一起。实际上,关系更 "deep" 和复杂。
在我的示例中,结果应该是这样的:
- 公司 A - 第 1 组
- 公司 B - 第 1 组
- 公司 C - 第 1 组
- 公司 D - 第 2 组
- 公司 E - 第 3 组
- 公司 F - 第 3 组
excel 中的示例 table:
我做了 3 table秒:
- SNAPSHOT_FO - 包含FO_CLUID(自然实体ID)
- SNAPSHOT_VAZBA - 包含 PO_cluid(法人实体 ID)和 FO_cluid。这就是关系 table.
- ODLITE - 包含 FO_CLUID(自然实体的 ID)和 KOD(组 ID) - 开头为空。应该是最后的 table 然后我可以加入 PO_cluid 并得到结果。
CREATE GLOBAL TEMPORARY TABLE tbl_temp
(
F_CL VARCHAR2(255) NULL,
par NUMBER(5) NULL
)
ON COMMIT PRESERVE ROWS;
DECLARE
party NUMBER := 1;
r NUMBER := 1;
BEGIN
FOR CLUID IN (select FO_CLUID from snapshot_fo WHERE ROWNUM =1)
LOOP
INSERT INTO tbl_temp (F_CL,par) VALUES (CLUID,party);
WHILE ( r> 0 )
BEGIN
MERGE INTO tbl_temp tg
USING ((SELECT distinct FO_CLUID from snapshot_vazba where PO_CLUID in (
SELECT distinct PO_CLUID
from snapshot_vazba
where FO_CLUID in (select f_cl from tbl_temp where kod=party)
))
) src
on (tg.FO_cluid =src.FO_cluid)
WHEN NOT MATCHED THEN
INSERT (F_CL, par)
VALUES (src.FO_CLUID, party)
SET r = SQL%ROWCOUNT
END;
INSERT INTO odlite (FO_CLUID, KOD) VALUES (tbl_temp.cluid,tbl_temp.party);
delete from snapshot_fo where fo_cluid in (select fo_cluid from odlite);
truncate table tbl_temp;
party := party + 1;
r := 1;
END Loop;
end ;
/
那我就把 table odlite
ON FO_cluid
加入我的 PO_cluid
table。
但是代码目前不起作用......而且我不知道如何做。
如果有更简单的方法,请告诉我:)
PS: 由于公司限制,我不能在声明部分临时table。
提前致谢!
Oracle SQL 开发人员版本 19.2.1.247
我没有完全理解正确的任务,但你可能需要它
select t1.po_cluid, t2.kod
from snapshot_vazba t1
join odlite t2 on t2.fo_cluid = t1.fo_cluid
group by t1.po_cluid, t2.kod
order by po_cluid, kod
然后您可以使用合并、插入 select、for 循环,或输入一个集合并根据需要进行处理
select po_cluid, dense_rank() over (order by min(connect_by_root(rn))) kod
from (select rownum rn, s.* from snapshot_vazba s) s
connect by nocycle prior fo_cluid = fo_cluid or prior po_cluid = po_cluid
group by po_cluid
此查询 returns 需要输出,但是如果 table 很大,恐怕对您的数据库来说会很重。期待性能问题。它在公司 - 合作伙伴 - 公司之间循环并找到最小共同价值。 Dense_rank()
仅用于按顺序枚举值。
declare
v_cluid varchar2(30 char);
v_party integer;
change_num integer;
function get_party return integer is
grp integer;
begin
select
nvl(max(kod),0)
into
grp
from
snapshot_vazba;
return grp;
end;
function get_cluid return varchar2 is
v_cluid varchar2(30 char);
begin
select
nvl(max(fo_cluid), 'XNA')
into
v_cluid
from
(
select
fo_cluid,
row_number() over (partition by 1 order by count_f desc) as rn
from
(
select count(1) as count_f, fo_cluid from snapshot_vazba where kod is null group by fo_cluid
)
)
where
rn = 1;
return v_cluid;
end;
begin
v_party := get_party + 1;
v_cluid := get_cluid;
while (v_cluid <> 'XNA' )
loop
update
snapshot_vazba
set
kod = v_party
where
po_cluid in (select po_cluid from snapshot_vazba where fo_cluid = v_cluid) and kod is null;
update
snapshot_vazba
set
kod = v_party
where
kod is null and
fo_cluid in (select fo_cluid from snapshot_vazba where kod = v_party);
change_num := sql%rowcount;
while (change_num > 0)
loop
update
snapshot_vazba
set
kod = v_party
where
po_cluid in (select po_cluid from snapshot_vazba where kod = v_party) and kod is null;
update
snapshot_vazba
set
kod = v_party
where
kod is null and
fo_cluid in (select fo_cluid from snapshot_vazba where kod = v_party);
change_num := sql%rowcount;
end loop;
commit;
v_party := v_party + 1;
v_cluid := get_cluid;
end loop;
end;
/
这有效:)
我是 PL/SQL 的新手,我正在努力完成我得到的任务。
我有法律实体和自然实体。每个法律实体都可以有一些自然实体,这些自然实体可以与 1 个或多个实体相关联。
- A 公司有客户#1、#2 和#3
- 公司 B 有客户 #2 和 #4
- 公司 C 有第 4 个不满
- 公司 D 有不满 #5
- 公司 E 有第 6 位客户
- F 公司有第 6 位客户
结果应显示哪些公司通过一些不一致的因素联系在一起。实际上,关系更 "deep" 和复杂。 在我的示例中,结果应该是这样的:
- 公司 A - 第 1 组
- 公司 B - 第 1 组
- 公司 C - 第 1 组
- 公司 D - 第 2 组
- 公司 E - 第 3 组
- 公司 F - 第 3 组
excel 中的示例 table:
我做了 3 table秒:
- SNAPSHOT_FO - 包含FO_CLUID(自然实体ID)
- SNAPSHOT_VAZBA - 包含 PO_cluid(法人实体 ID)和 FO_cluid。这就是关系 table.
- ODLITE - 包含 FO_CLUID(自然实体的 ID)和 KOD(组 ID) - 开头为空。应该是最后的 table 然后我可以加入 PO_cluid 并得到结果。
CREATE GLOBAL TEMPORARY TABLE tbl_temp
(
F_CL VARCHAR2(255) NULL,
par NUMBER(5) NULL
)
ON COMMIT PRESERVE ROWS;
DECLARE
party NUMBER := 1;
r NUMBER := 1;
BEGIN
FOR CLUID IN (select FO_CLUID from snapshot_fo WHERE ROWNUM =1)
LOOP
INSERT INTO tbl_temp (F_CL,par) VALUES (CLUID,party);
WHILE ( r> 0 )
BEGIN
MERGE INTO tbl_temp tg
USING ((SELECT distinct FO_CLUID from snapshot_vazba where PO_CLUID in (
SELECT distinct PO_CLUID
from snapshot_vazba
where FO_CLUID in (select f_cl from tbl_temp where kod=party)
))
) src
on (tg.FO_cluid =src.FO_cluid)
WHEN NOT MATCHED THEN
INSERT (F_CL, par)
VALUES (src.FO_CLUID, party)
SET r = SQL%ROWCOUNT
END;
INSERT INTO odlite (FO_CLUID, KOD) VALUES (tbl_temp.cluid,tbl_temp.party);
delete from snapshot_fo where fo_cluid in (select fo_cluid from odlite);
truncate table tbl_temp;
party := party + 1;
r := 1;
END Loop;
end ;
/
那我就把 table odlite
ON FO_cluid
加入我的 PO_cluid
table。
但是代码目前不起作用......而且我不知道如何做。
如果有更简单的方法,请告诉我:)
PS: 由于公司限制,我不能在声明部分临时table。
提前致谢!
Oracle SQL 开发人员版本 19.2.1.247
我没有完全理解正确的任务,但你可能需要它
select t1.po_cluid, t2.kod
from snapshot_vazba t1
join odlite t2 on t2.fo_cluid = t1.fo_cluid
group by t1.po_cluid, t2.kod
order by po_cluid, kod
然后您可以使用合并、插入 select、for 循环,或输入一个集合并根据需要进行处理
select po_cluid, dense_rank() over (order by min(connect_by_root(rn))) kod
from (select rownum rn, s.* from snapshot_vazba s) s
connect by nocycle prior fo_cluid = fo_cluid or prior po_cluid = po_cluid
group by po_cluid
此查询 returns 需要输出,但是如果 table 很大,恐怕对您的数据库来说会很重。期待性能问题。它在公司 - 合作伙伴 - 公司之间循环并找到最小共同价值。 Dense_rank()
仅用于按顺序枚举值。
declare
v_cluid varchar2(30 char);
v_party integer;
change_num integer;
function get_party return integer is
grp integer;
begin
select
nvl(max(kod),0)
into
grp
from
snapshot_vazba;
return grp;
end;
function get_cluid return varchar2 is
v_cluid varchar2(30 char);
begin
select
nvl(max(fo_cluid), 'XNA')
into
v_cluid
from
(
select
fo_cluid,
row_number() over (partition by 1 order by count_f desc) as rn
from
(
select count(1) as count_f, fo_cluid from snapshot_vazba where kod is null group by fo_cluid
)
)
where
rn = 1;
return v_cluid;
end;
begin
v_party := get_party + 1;
v_cluid := get_cluid;
while (v_cluid <> 'XNA' )
loop
update
snapshot_vazba
set
kod = v_party
where
po_cluid in (select po_cluid from snapshot_vazba where fo_cluid = v_cluid) and kod is null;
update
snapshot_vazba
set
kod = v_party
where
kod is null and
fo_cluid in (select fo_cluid from snapshot_vazba where kod = v_party);
change_num := sql%rowcount;
while (change_num > 0)
loop
update
snapshot_vazba
set
kod = v_party
where
po_cluid in (select po_cluid from snapshot_vazba where kod = v_party) and kod is null;
update
snapshot_vazba
set
kod = v_party
where
kod is null and
fo_cluid in (select fo_cluid from snapshot_vazba where kod = v_party);
change_num := sql%rowcount;
end loop;
commit;
v_party := v_party + 1;
v_cluid := get_cluid;
end loop;
end;
/
这有效:)