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

階層データセットで複雑な合計を計算するのに役立ちます

    Oracle 11 R2では、common table expressionで可能です。 :

    テストデータ:

    --  drop table assembly;
    
    create table assembly (
      part_id              number, 
      parent_part_id       number,
      quantity             number
    );
    
    insert into assembly values (2, 1,  2);
    insert into assembly values (3, 2, 10);
    insert into assembly values (4, 1,  2);
    insert into assembly values (5, 4,  1);
    insert into assembly values (3, 5,  5);
    

    selectステートメント:

    select 
      part_id, 
      sum(quantity_used) as quantity
    from (
      with assembly_hier (lvl, part_id, quantity, quantity_used) as (
        select 
          1        lvl,
          part_id,
          quantity ,
          quantity        quantity_used
        from
          assembly
        where
          parent_part_id = 1 
      union all
        select
          assembly_hier.lvl      + 1 lvl,
          assembly     .part_id,
          assembly     .quantity,
          assembly_hier.quantity_used * assembly.quantity quantity_used
        from
          assembly_hier, assembly
        where
          assembly_hier.part_id = assembly.parent_part_id
      )
      select * from assembly_hier
    )
    group by part_id
    order by part_id;
    

    編集 Ora11R2より前は、model clauseで機能する可能性がありました。 :

    select 
      part_id,
      sum(quantity) quantity 
    from (
      select
        lvl
        parent_part_id,
        part_id,
        quantity
      from (
        select 
          lvl,
          parent_part_id,
          part_id,
          quantity
        from (
          select  
            rownum r, 
            level lvl, 
            parent_part_id,
            part_id, 
            quantity
          from 
            assembly
          start with parent_part_id = 1
          connect by parent_part_id = prior part_id
        )
      )
      model
        dimension by (lvl, part_id)
        measures (quantity, parent_part_id)
        rules upsert (
           quantity[     any, any          ] order by lvl, part_id =   quantity[cv(lvl)  , cv(part_id)] * 
                                              nvl( quantity[cv(lvl)-1,    parent_part_id[cv(lvl), cv(part_id)] ], 1)
        )
    )
    group by part_id
    order by part_id;
    

    編集II もう1つの可能性は、数量の対数を合計してから、合計の指数を取得することです。

    select 
      part_id,
      sum(quantity) quantity
    from (
      select 
        part_id,
        exp(sum(quantity_ln) over (partition by new_start order by r)) quantity
      from (
        select 
          r,
          lvl,
          part_id,
          quantity_ln,
          sum(new_start) over(order by r) new_start
        from (
          select 
            rownum r, 
            level lvl, 
            part_id, 
            ln(quantity) quantity_ln,
            nvl(lag(connect_by_isleaf,1) over (order by rownum),0) new_start
          from assembly
          start with parent_part_id = 1
          connect by parent_part_id = prior part_id
        )
      )
    )
    group by part_id
    order by part_id
    ;
    


    1. 続編の移行と初期化を処理するためのワークフロー?

    2. デフォルト値であるmysqlのcurrrent_timestampに1時間を追加するにはどうすればよいですか?

    3. Laravelモデルを使用してデータベースビューにアクセスするにはどうすればよいですか?

    4. phpスクリプトでWordpressユーザー資格情報を使用してiOSアプリにデータを送信する