Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Bagaimana cara melakukan penghitungan pada Tabel Hirarki Oracle berdasarkan Tautan Induk?

Untuk memilih data coba ini:

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
        ))
;

Pada set pengujian 39000 catatan, dibutuhkan Intel Core i5 dengan Oracle 11.2 (dan cache buffer yang dihapus) kira-kira 0,15 detik untuk menghitung ini. Saya harap ini cukup cepat untuk memenuhi kebutuhan Anda.

Untuk memperbarui tabel target dengan data ini, baik loop melalui SELECT di atas dan perbarui link_counts Anda tabel secara iteratif, atau cukup gunakan MERGE pernyataan:

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 mengasumsikan bahwa GROUP_ID adalah kunci utama/unik di link_counts meja. Definisi sebenarnya dari tech_values tabel di pertanyaan awal mendukung asumsi ini.

Spool uji coba di SQL*Plus adalah sebagai berikut:

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mengapa OCI8/Oracle PHP oci_bind_array_by_name tidak berfungsi untuk saya?

  2. Entitas Oracle dalam kerangka entitas VS tidak memperbarui kunci utama dalam kode

  3. sql statis vs dinamis

  4. Menggunakan urutan Oracle untuk memasukkan id log ke dalam 2 tabel dari jdbc?

  5. Beberapa pertanyaan oracle masalah