Sql 按普通人分组递归循环

Sql 按普通人分组递归循环,sql,oracle,plsql,cursor,cycle,Sql,Oracle,Plsql,Cursor,Cycle,我对PL/SQL非常陌生,我正在为我得到的任务而挣扎 我有法律实体和自然实体。每个法律实体可以有一些自然实体,这些自然实体可以与一个或多个实体相关联 A公司有争议1、2和3 B公司有争议2和4 C公司有争议4 D公司有争议 E公司有异议 F公司有异议 结果应该表明哪些公司通过一些纠纷联系在一起。在现实中,两者的关系更为深刻和复杂。 在我的例子中,结果应该是这样的: A公司-第一组 B公司-第一组 C公司-第一组 D公司-第2组 E公司-第3组 F公司-第3组 excel中的示例表: 我做了三张桌

我对PL/SQL非常陌生,我正在为我得到的任务而挣扎

我有法律实体和自然实体。每个法律实体可以有一些自然实体,这些自然实体可以与一个或多个实体相关联

A公司有争议1、2和3 B公司有争议2和4 C公司有争议4 D公司有争议 E公司有异议 F公司有异议 结果应该表明哪些公司通过一些纠纷联系在一起。在现实中,两者的关系更为深刻和复杂。 在我的例子中,结果应该是这样的:

A公司-第一组 B公司-第一组 C公司-第一组 D公司-第2组 E公司-第3组 F公司-第3组 excel中的示例表:

我做了三张桌子:

快照\u FO-包含自然实体的FO\u CLUID ID SNAPSHOT_VAZBA-包含法人实体的订单ID和订单ID。这是关系表。 ODLITE-包含自然实体的fou_CLUID ID和KOD组ID-开头为空。应该是最后一个表,我可以加入PO_cluid并得到结果。 创建全局临时表tbl\U temp F_CL VARCHAR2255空, 票数5 在提交保存行上; 声明 参与方编号:=1; r数:=1; 开始 对于中的CLUID,请从快照中选择FO CLUID,其中ROWNUM=1 环 插入TBLL TEFP FEL CL,PAR值CULID,方; 当r>0时 开始 合并到tbl_temp tg中 使用从快照中选择不同的fou_CLUID,其中PO_CLUID位于 选择不同的PO_CLUID 来自斯库瓦兹巴 其中FO_CLUID in select f_cl from tbl_temp,其中kod=参与方 src 关于tg.FO_cluid=src.FO_cluid 当不匹配时 插入FEL CL 值src.fou_CLUID,参与方 设置r=SQL%ROWCOUNT 终止 在odlite FO_CLUID中插入KOD值tbl_temp.CLUID,tbl_temp.party; 从快照中删除,其中从odlite中选择fo_cluid中选择fo_cluid; 截断表tbl_temp; 参与方:=参与方+1; r:=1; 端环; 终止 / 然后我将把fou_cluid上的表odlite连接到我的PO_cluid表中。 但代码目前不起作用。。。我不知道还有什么别的办法。 如果有更简单的方法,请告诉我:

注:由于我们公司的限制,我不允许在申报部分制作临时表格

提前谢谢


ORACLE SQL DEVELOPER 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

然后您可以使用merge、insert-into-select、for-loop或键入一个集合,并根据需要对其进行处理

我没有完全正确地理解该任务,但您可能需要它

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 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
然后可以在集合中使用“合并”、“插入到选择”、“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
此查询返回所需的输出,但若表很大,恐怕会对数据库造成很大的负担。预期性能问题。它在company-disponent-company之间循环,并找到最小的公共值。密集秩仅用于按顺序枚举值

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;
/
此查询返回所需的输出,但若表很大,恐怕会对数据库造成很大的负担。预期性能问题。它在company-disponent-company之间循环,并找到最小的公共值。密集秩仅用于按顺序枚举值

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;
/
这项工作:


这是有效的:

我也在考虑Previor和Connect By,但我不确定是否可以将其用于我的问题。我也在考虑Previor和Connect By,但我不确定是否可以将其用于我的问题。欢迎使用SO Pavel。请复习。以此作为你问题的模板,大大增加了你得到满意答案的机会。特别是所有表和样本数据的post DDL(均为文本,无图像)以及该数据的预期结果。就你的PS而言:你的公司做得很好;至少对于Oracle。表Odlite在开始时是空的。我只是展示了它应该如何看结尾。您需要一个聚合属性。否则,使用链接映射很难显示所需的数据欢迎访问SO Pavel。请复习。以此作为你问题的模板,大大增加了你得到满意答案的机会。特别是所有表和样本数据的post DDL(均为文本,无图像)以及该数据的预期结果。就你的PS而言:你的公司做得很好;至少对于Oracle。表Odlite在开始时是空的。我只是展示了结尾应该是什么样子。你需要一个aggr
egation属性。否则,使用链接映射很难显示所需的数据是:/I我也在考虑Previor和Connect By,但数据集太大,太复杂。我有7万多家公司,有些公司有200多个分机,有些分机连接到200多家公司。。但是谢谢你!这肯定是针对较小数据集的解决方案。是的:/I我也在考虑Previor和Connect By,但数据集太大,太复杂,无法实现这一点。我有7万多家公司,有些公司有200多个分机,有些分机连接到200多家公司。。但是谢谢你!这无疑是较小数据集的解决方案。