sql >> Database teknologi >  >> RDS >> Oracle

Hvordan udfører man tællinger på en Oracle Hierarkisk tabel baseret på Parent Link?

For at vælge data, prøv dette:

with xyz as (
    select tech_type,
        connect_by_root(link_id) as root_link_id,
        connect_by_root(group_id) as root_group_id
    from tech_values
    start with parent_group_id = 0
    connect by prior group_id = parent_group_id
)
select root_link_id, root_group_id,
    a_tech_type as tech_type_a, b_tech_type as tech_type_b, c_tech_type as tech_type_c
from xyz pivot (
        count(1) as tech_type
        for tech_type in (
            'A' as A,
            'B' as B,
            'C' as C
        ))
;

På et testsæt på 39000 poster tog det en Intel Core i5 med Oracle 11.2 (og skyllet buffercache) ca. 0,15 sek. at beregne dette. Jeg håber, det er hurtigt nok til at tilfredsstille dine behov.

For at opdatere måltabellen med disse data skal du enten gå gennem SELECT ovenfor og opdater dine link_counts tabel iterativt, eller brug blot MERGE erklæring:

merge into link_counts T
using (
    with xyz as (
        select tech_type,
            connect_by_root(link_id) as root_link_id,
            connect_by_root(group_id) as root_group_id
        from tech_values X
        start with parent_group_id = 0
        connect by prior group_id = parent_group_id
    )
    select *
    from xyz pivot (
            count(1) as tech_type
            for tech_type in (
                'A' as A,
                'B' as B,
                'C' as C
            ))
) S
on ( T.group_id = S.root_group_id )
when matched then
    update
    set T.tech_type_a = S.a_tech_type,
        T.tech_type_b = S.b_tech_type,
        T.tech_type_c = S.c_tech_type
when not matched then
    insert (link_id, group_id, tech_type_a, tech_type_b, tech_type_c)
    values (S.root_link_id, S.root_group_id, S.a_tech_type, S.b_tech_type, S.c_tech_type)
;

MERGE antager, at GROUP_ID er en primær/unik nøgle i link_counts bord. Den faktiske definition af tech_values tabel i det oprindelige spørgsmål understøtter denne antagelse.

En spool af en testkørsel i SQL*Plus er som følger:

SQL> 
SQL> select count(1)
  2  from user_indexes
  3  where table_name = 'TECH_VALUES'
  4  ;

  COUNT(1)
----------
         0

SQL> 
SQL> select count(1)
  2  from user_constraints
  3  where table_name = 'TECH_VALUES'
  4      and constraint_type != 'C'
  5  ;

  COUNT(1)
----------
         0

SQL> 
SQL> alter system flush buffer_cache;

System altered.

SQL> alter system flush shared_pool;

System altered.

SQL> 
SQL> select systimestamp from dual;

SYSTIMESTAMP
---------------------------------------------------------------------------
08.06.14 23:18:40,053000 +02:00

SQL> 
SQL> select tech_type, count(1)
  2  from tech_values
  3  where parent_group_id != 0
  4  group by rollup(tech_type);

T   COUNT(1)
- ----------
A      20048
B      39984
C      19984
       80016

SQL> 
SQL> select systimestamp from dual;

SYSTIMESTAMP
---------------------------------------------------------------------------
08.06.14 23:18:40,144000 +02:00

SQL> 
SQL> alter system flush buffer_cache;

System altered.

SQL> alter system flush shared_pool;

System altered.

SQL> 
SQL> select systimestamp from dual;

SYSTIMESTAMP
---------------------------------------------------------------------------
08.06.14 23:18:40,246000 +02:00

SQL> 
SQL> with xyz as (
  2      select connect_by_root(link_id) as root_link_id, connect_by_root(group_id) as root_group_id, tech_type
  3      from tech_values X
  4      start with parent_group_id = 0
  5      connect by prior group_id = parent_group_id
  6  )
  7  select *
  8  from xyz pivot (
  9          count(1) as tech_type
 10          for tech_type in (
 11          'A' as A,
 12          'B' as B,
 13          'C' as C
 14          ));

ROOT_LINK_ID                                                     ROOT_GROUP_ID A_TECH_TYPE B_TECH_TYPE C_TECH_TYPE
---------------------------------------------------------------- ------------- ----------- ----------- -----------
LETTER_B                                                                  1800        3667        7482        3854
LETTER_B                                                                   200        3712        7583        3708
LETTER_C                                                                   300        6326       12450        6229
LETTER_A                                                                   100        6343       12469        6193

SQL> 
SQL> select *
  2  from table(dbms_xplan.display_cursor())
  3  ;

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  59hmrtw6q3f4u, child number 0
-------------------------------------
with xyz as (     select connect_by_root(link_id) as root_link_id,
connect_by_root(group_id) as root_group_id, tech_type     from
tech_values X     start with parent_group_id = 0     connect by prior
group_id = parent_group_id ) select * from xyz pivot (         count(1)
as tech_type         for tech_type in (             'A' as A,
  'B' as B,             'C' as C         ))

Plan hash value: 3833790953

-------------------------------------------------------------------------------------------
| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |             |       |       |   563 (100)|          |
|   1 |  HASH GROUP BY PIVOT        |             | 29102 |  1420K|   563   (1)| 01:23:35 |
|   2 |   VIEW                      |             | 29102 |  1420K|  1044  (47)| 02:35:00 |
|*  3 |    CONNECT BY WITH FILTERING|             |       |       |            |          |
|*  4 |     TABLE ACCESS FULL       | TECH_VALUES |     4 |    84 |   187   (0)| 00:27:46 |
|*  5 |     HASH JOIN               |             | 29098 |   966K|   375   (1)| 00:55:41 |
|   6 |      CONNECT BY PUMP        |             |       |       |            |          |
|   7 |      TABLE ACCESS FULL      | TECH_VALUES | 80020 |  1641K|   187   (0)| 00:27:46 |
-------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("PARENT_GROUP_ID"=PRIOR NULL)
   4 - filter("PARENT_GROUP_ID"=0)
   5 - access("connect$_by$_pump$_002"."prior group_id "="PARENT_GROUP_ID")


31 rows selected.

SQL> 
SQL> select systimestamp from dual;

SYSTIMESTAMP
---------------------------------------------------------------------------
08.06.14 23:18:40,805000 +02:00

SQL> 
SQL> spool off



  1. 50 Shades of Oracle Database Certificeringseksamen

  2. Standard getdate for Indsæt dato

  3. Hvordan tilføjer man en JDBC-driver til en Jenkins-pipeline?

  4. mysqli_stmt::bind_param() - angiv en anden datatype end s for hver parameter