sql >> データベース >  >> RDS >> Oracle

親リンクに基づいて Oracle 階層テーブルでカウントを実行する方法は?

    データを選択するには、これを試してください:

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

    39000 レコードのテスト セットでは、Oracle 11.2 (およびフラッシュされたバッファ キャッシュ) を搭載した Intel Core i5 で、これを計算するのに約 0.15 秒かかりました。あなたのニーズを満たすのに十分な速さであることを願っています.

    これらのデータでターゲット テーブルを更新するには、上記の SELECT をループします。 link_counts を更新します テーブルを繰り返し使用するか、単に MERGE を使用します ステートメント:

    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 GROUP_IDlink_counts のプライマリ/一意のキーです テーブル。 tech_values の実際の定義 元の質問の表は、この仮定をサポートしています。

    SQL*Plus でのテスト実行のスプールは次のとおりです:

    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. Rank()SQLまたはそのようなもの

    2. Replace() を使用した SELECT

    3. この Oracle 接続エラーが発生するのはなぜですか? ORA-12519、TNS:適切なサービス・ハンドラが見つかりません

    4. SQLストアドプロシージャの実行時間の違い