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

分析機能が機能するように、後続のAPのゼロ値レコードを動的に追加します

    かなり単純なアプローチ(およびAskTomリンクが示すものと同様)は、すべての年/月のペア、およびすべての名前/ r_groupのペアを抽出し、それらを相互結合することです。

    with data as (
      select 1 id, 'A' name, 'fruit' r_group, '2007' year, '04' month, 5 sales from dual union all
      select 2 id, 'Z' name, 'fruit' r_group, '2007' year, '04' month, 99 sales from dual union all
      select 3 id, 'A' name, 'fruit' r_group, '2008' year, '05' month, 10 sales from dual union all
      select 4 id, 'B' name, 'vegetable' r_group, '2008' year, '07' month, 20 sales from dual
    )
    select a.year, a.month, b.name, b.r_group, nvl(d.sales, 0) as sales
    from (select distinct year, month from data) a
    cross join (select distinct name, r_group from data) b
    left join data d on d.year = a.year and d.month = a.month and d.name = b.name and d.r_group = b.r_group
    order by year, month, name, r_group;
    
    YEAR MO N R_GROUP        SALES
    ---- -- - --------- ----------
    2007 04 A fruit              5
    2007 04 B vegetable          0
    2007 04 Z fruit             99
    2008 05 A fruit             10
    2008 05 B vegetable          0
    2008 05 Z fruit              0
    2008 07 A fruit              0
    2008 07 B vegetable         20
    2008 07 Z fruit              0
    

    ただし、これにより、最初のレベルの集計で必要な行よりも多くの行が生成されます。

    YEAR MO N R_GROUP        SALES    OPENING    CLOSING
    ---- -- - --------- ---------- ---------- ----------
    2007 04 A fruit              5          0          5
    2007 04 B vegetable          0          0          0
    2007 04 Z fruit             99          0         99
    2008 05 A fruit             10          5         15
    2008 05 B vegetable          0          0          0
    2008 05 Z fruit              0         99         99
    2008 07 A fruit              0         15         15
    2008 07 B vegetable         20          0         20
    2008 07 Z fruit              0         99         99
    

    また、(他のクエリからの)2番目のレベルで集計すると、たとえば2007/04/vegetableの追加の行が生成されます。

    YEAR MO R_GROUP        SALES    OPENING    CLOSING
    ---- -- --------- ---------- ---------- ----------
    2007 04 fruit            104          0        104
    2007 04 vegetable          0          0          0
    2008 05 fruit             10        104        114
    2008 05 vegetable          0          0          0
    2008 07 fruit              0        114        114
    2008 07 vegetable         20          0         20
    

    すべての中間列がゼロになるため、集計する前にそれらを部分的に除外できます。

    with data as (
      select 1 id, 'A' name, 'fruit' r_group, '2007' year, '04' month, 5 sales from dual union all
      select 2 id, 'Z' name, 'fruit' r_group, '2007' year, '04' month, 99 sales from dual union all
      select 3 id, 'A' name, 'fruit' r_group, '2008' year, '05' month, 10 sales from dual union all
      select 4 id, 'B' name, 'vegetable' r_group, '2008' year, '07' month, 20 sales from dual
    )
    select year,
           month,
           r_group,
           sum(sales) sales,
           sum(opening) opening,
           sum(closing) closing
    from (
      select t.*,
             (sum(sales) over (partition by name, r_group
                               order by year, month
                               rows between unbounded preceding and current row
                              ) -sales ) as opening,
             sum(sales) over (partition by name, r_group
                              order by year, month
                              rows between unbounded preceding and current row
                             ) as closing
      from (
        select a.year, a.month, b.name, b.r_group, nvl(d.sales, 0) as sales
        from (select distinct year, month from data) a
        cross join (select distinct name, r_group from data) b
        left join data d
        on d.year = a.year and d.month = a.month and d.name = b.name and d.r_group = b.r_group
      ) t
    )
    where sales != 0 or opening != 0 or closing != 0
    group by year, month, r_group
    order by year, month;
    

    取得するには:

    YEAR MO R_GROUP        SALES    OPENING    CLOSING
    ---- -- --------- ---------- ---------- ----------
    2007 04 fruit            104          0        104
    2008 05 fruit             10        104        114
    2008 07 fruit              0        114        114
    2008 07 vegetable         20          0         20
    

    その結果をさらにフィルタリングして、集計された売上値がまだゼロである行を削除することもできますが、それを実行している場合は、でフィルタリングします。 集約はもう必要ありません。しかし、それはまだ少し厄介です。そして、それを行うために最も外側の集計を変更できるかどうかは明らかではありません。



    1. Android RoomEmbeddedRelationはSQLwhere条件を無視します

    2. Jqueryのタイムスタンプとphpのタイムスタンプの違いは?

    3. MySQLALTERTABLEがハングする

    4. MySQL-SELECTクエリに基づくUPDATEクエリ