如何有效地求和,当行应该在更多组中时 Oracle

how to sum effectively, when rows should be in more groups Oracle

我有一些记录(超过 100 万条)由公司组组成,但有些记录属于几个组,我需要得到组的总和(主要(C216 列)和次要([= 列) 30=]))

第LIST_OF_PARENT_CCN列是任意数量的组ID,分号为“,”,可以在tableRR_SRC_LEK_P5中看到。

我创建了 table 公司组和总和 (RR_SRC_LEK_P5) 并通过光标填充总和。此解决方案有效,但速度慢且无效。

table RR_SRC_LEK_P5 看起来像:

C216        LIST_OF_PARENT_CCN ESS_SUM
00004146    4523401            0
00005354    5487228, 2103188   0
00006203                       0
00007524    2196702, 2103188   0
00009164    2163921, 4523401   0

table RR_SRC_LEK_P6 仅包含 PARENT_CCN

的总和
PARENT_CCN ESS_SUM
4523401    258418650,7711
5487228    2534044,19664
2103188    13482783356,0255
2196702    9936875,58
2163921    141329781,3349

结果应该是这样的,offcourse in column ESS_SUM 只有一个数字

C216        LIST_OF_PARRENT_CCN ESS_SUM
00004146    4523401             258418650,7711
00005354    5487228, 2103188    2534044,19664 + 2534044,19664
00006203                        0
00007524    2196702, 2103188    9936875,58 + 13482783356,0255
00009164    2163921, 4523401    141329781,3349 + 4523401       

有游标,我用的是立即执行

 CREATE OR REPLACE PROCEDURE CURSOR_TEST AS 
    c_sql sys_refcursor;
    c_C216 RR_SRC_LEK_P5.C216%TYPE;
    c_LIST_OF_PARENT_CCN RR_SRC_LEK_P5.LIST_OF_PARENT_CCN%TYPE;

    BEGIN

         OPEN c_sql for 'select C216, LIST_OF_PARENT_CCN from RR_SRC_LEK_P5 where LIST_OF_PARENT_CCN is not null';
            LOOP 
              FETCH c_sql into c_C216, c_LIST_OF_PARENT_CCN; 
                EXIT WHEN c_sql%notfound;

                execute immediate 'update RR_SRC_LEK_P5 a set
                                   ESS_SUM = (select sum(ESS_SUM) from RR_SRC_LEK_P6 where PARENT_CCN in (' || c_LIST_OF_PARENT_CCN || '))
                                   where a.C216 = ''' || c_C216 || '''';

            END LOOP; 
          CLOSE c_sql;
          commit;
    END CURSOR_TEST;

有没有比使用游标更好的方法?

您可以将 aggregate 函数与 xmlquery 一起使用:

Table 创建:

SQL> CREATE TABLE RR_SRC_LEK_P5  AS (
  2  SELECT '00004146' AS C216, '4523401' AS LIST_OF_PARENT_CCN, 0 AS ESS_SUM FROM DUAL UNION ALL
  3  SELECT '00005354',    '5487228, 2103188',   0 FROM DUAL UNION ALL
  4  SELECT '00006203',    NULL                  ,0 FROM DUAL UNION ALL
  5  SELECT '00007524',    '2196702, 2103188',   0 FROM DUAL UNION ALL
  6  SELECT '00009164',    '2163921, 4523401',   0 FROM DUAL);

Table created.

SQL> CREATE TABLE RR_SRC_LEK_P6 AS
  2  (SELECT 4523401 AS PARENT_CCN,    2584186507711 AS ESS_SUM  FROM DUAL UNION ALL
  3  SELECT 5487228,    253404419664    FROM DUAL UNION ALL
  4  SELECT 2103188,    134827833560255 FROM DUAL UNION ALL
  5  SELECT 2196702,    993687558       FROM DUAL UNION ALL
  6  SELECT 2163921,    1413297813349   FROM DUAL);

Table created.
SQL>

查看当前数据

SQL> select * from RR_SRC_LEK_P5;

C216     LIST_OF_PARENT_C    ESS_SUM
-------- ---------------- ----------
00004146 4523401                   0
00005354 5487228, 2103188          0
00006203                           0
00007524 2196702, 2103188          0
00009164 2163921, 4523401          0

SQL> select * from RR_SRC_LEK_P6;

PARENT_CCN                                 ESS_SUM
---------- ---------------------------------------
   4523401                           2584186507711
   5487228                            253404419664
   2103188                         134827833560255
   2196702                               993687558
   2163921                           1413297813349

SQL>

查询更新数据

SQL>
SQL> MERGE INTO RR_SRC_LEK_P5 P5
  2  USING ( SELECT P5.C216,
  3                  XMLQUERY(
  4                    LISTAGG(P6.ESS_SUM, '+') WITHIN GROUP (ORDER BY NULL)
  5                    RETURNING CONTENT ).GETNUMBERVAL() AS ESS_NEW
  6          FROM RR_SRC_LEK_P5 P5
  7          JOIN RR_SRC_LEK_P6 P6
  8              ON ( INSTR(', ' || P5.LIST_OF_PARENT_CCN || ',',
  9                         ', ' || P6.PARENT_CCN || ',') > 0 )
 10          GROUP BY P5.C216) RES
 11  ON ( P5.C216 = RES.C216 )
 12  WHEN MATCHED THEN
 13  UPDATE SET P5.ESS_SUM = RES.ESS_NEW;

4 rows merged.
SQL>

更新数据

SQL> SELECT * FROM RR_SRC_LEK_P5;

C216     LIST_OF_PARENT_C                                 ESS_SUM
-------- ---------------- ---------------------------------------
00004146 4523401                                    2584186507711
00005354 5487228, 2103188                         135081237979919
00006203                                                        0
00007524 2196702, 2103188                         134828827247813
00009164 2163921, 4523401                           3997484321060

SQL>

DB<>Fiddle demo

更新

对于您的设置,您需要使用以下查询:

MERGE INTO RR_SRC_LEK_P5 P5
    USING ( SELECT P5.C216,
                    XMLQUERY(
                      LISTAGG(
                      to_char(p6.ESS_SUM, 
                      'fm9999999999999999999999999999D099999999999999999',
                      'nls_numeric_characters = ''.,'''), '+') WITHIN GROUP (ORDER BY NULL)
                      RETURNING CONTENT ).GETNUMBERVAL() AS ESS_NEW
            FROM RR_SRC_LEK_P5 P5
            JOIN RR_SRC_LEK_P6 P6
                ON ( INSTR(', ' || P5.LIST_OF_PARENT_CCN || ',',
                          ', ' || P6.PARENT_CCN || ',') > 0 )
           GROUP BY P5.C216) RES
   ON ( P5.C216 = RES.C216 )
   WHEN MATCHED THEN
   UPDATE SET P5.ESS_SUM = RES.ESS_NEW;

干杯!!