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

ORACLEでのトリッキーなGROUPBYの問題

    Oracle 11では、pivotを使用できます。 unpivotと一緒に句 条項:

    with 
    count_table as (
         select 1001 device_id,  4 quantity from dual union all
         select 1002 device_id, 20 quantity from dual union all
         select 1003 device_id,  1 quantity from dual 
    ),
    device_table as (
         select 1001 id, 'Yes'     wifi, 'No'       email, 'No'  bluetooth from dual union all
         select 1002 id, 'Yes'     wifi, 'Yes'      email, 'No'  bluetooth from dual union all
         select 1003 id, 'Unknown' wifi, 'Unknown'  email, 'Yes' bluetooth from dual 
    )
    ----------------------------------------
    select * from (
          select
            feature,
            yes_no_unknown,
            sum(quantity)  quantity
          from 
             count_table  c join 
             device_table d on c.device_id = d.id
          unpivot  ( yes_no_unknown
                     for feature in (wifi, email, bluetooth)
          ) 
          group by 
          feature,
          yes_no_unknown
    )  
    pivot ( sum (quantity)
            for yes_no_unknown in ('Yes' as yes, 'No' as no, 'Unknown' as unknown)
    )
    ;
    

    または、2つの既存のテーブルを、必要な3つの行の値を含む3番目のテーブルに結合することもできます。おそらく少し読みやすいでしょう:

    with 
    count_table as (
         select 1001 device_id,  4 quantity from dual union all
         select 1002 device_id, 20 quantity from dual union all
         select 1003 device_id,  1 quantity from dual 
    ),
    device_table as (
         select 1001 id, 'Yes'     wifi, 'No'       email, 'No'  bluetooth from dual union all
         select 1002 id, 'Yes'     wifi, 'Yes'      email, 'No'  bluetooth from dual union all
         select 1003 id, 'Unknown' wifi, 'Unknown'  email, 'Yes' bluetooth from dual 
    )
    ----------------------------------------
    select
       f.txt,
       sum(case when ( f.txt = 'wifi'      and d.wifi      = 'Yes' ) or
                     ( f.txt = 'email'     and d.email     = 'Yes' ) or
                     ( f.txt = 'bluetooth' and d.bluetooth = 'Yes' ) 
                then   c.quantity
                else   0 end
          ) yes,
       sum(case when ( f.txt = 'wifi'      and d.wifi      = 'No' ) or
                     ( f.txt = 'email'     and d.email     = 'No' ) or
                     ( f.txt = 'bluetooth' and d.bluetooth = 'No' ) 
                then   c.quantity
                else   0 end
          ) no,
       sum(case when ( f.txt = 'wifi'      and d.wifi      = 'Unknown' ) or
                     ( f.txt = 'email'     and d.email     = 'Unknown' ) or
                     ( f.txt = 'bluetooth' and d.bluetooth = 'Unknown' ) 
                then   c.quantity
                else   0 end
          ) unknown
    from 
       count_table  c                                   join 
       device_table d on c.device_id = d.id     cross   join
       (
            select 'wifi'      txt from dual union all
            select 'email'     txt from dual union all
            select 'bluetooth' txt from dual
       ) f
    group by 
        f.txt;
    


    1. PHPの2つのmysqlテーブルからのJson

    2. 個々のIDに対する合計を見つけるためのSQLクエリ

    3. PHPの管理者によるユーザーの追加、削除、編集

    4. ストアドプロシージャから複数の行を返す方法は? (Oracle PL / SQL)