2016-06-15 4 views
-1

入力し、コードを使用してクエリでゼロ値のレコードを追加:は累積的な分析機能に

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 data t 
) 
group by year, month, r_group 
order by year, month 

出力:

year | month | r_group | sales | opening | closing | 
2007 |  04 | fruit | 104 | 0  | 104  | 
2008 |  05 | fruit | 10  | 104 | 114  | 
2008 |  07 | vegetable | 20  | 0  | 20  | 

year | month | r_group | sales | opening | closing | 
2007 |  04 | fruit | 104 | 0  | 104  | 
2008 |  05 | fruit | 10  | 5  | 15  | 
2008 |  07 | vegetable | 20  | 0  | 20  | 

は、私は、出力は次のようになりたいです

私は、月= 05のデータにゼロ値レコードを追加し、tのようにname = 'Z'彼自身:

ただし、データを編集することなく選択クエリの一部としてこれを実行できるかどうかを知りたいと思います。

EDIT

内側のselect文になるデータベーステーブルへの入力詳細版:年、月、名前、r_group、オープニング、クロージングを。 (サードパーティを

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 data t 

が、私は分析ツールを使用して、その上で集計を使用します:つまり、このクエリの結果は、dbテーブルを移入して、その後どうなるの外側のクエリを使用して凝集するために使用されます)を指定すると、r_groupに集約されます。しかし、年、月、名前、r_groupの詳細はバックグラウンドに存在しなければなりません。他のworkdsで

EDIT 2

、私は動的に不足しているデータを追加しようとしています。たとえば、name = 'Z'が2007,04に存在していても2008,05にない場合、累積関数は2008になると失敗します。それは失敗する。

SELECT t.*, 
     SUM(sales) OVER (PARTITION BY r_group, dt) AS r_group_month_sales, 
     COALESCE(
     SUM(sales) OVER (
      PARTITION BY r_group 
      ORDER BY dt 
      RANGE BETWEEN UNBOUNDED PRECEDING AND INTERVAL '1' MONTH PRECEDING 
     ), 
     0 
     ) AS opening, 
     SUM(sales) OVER (
     PARTITION BY r_group 
     ORDER BY dt 
     RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
     ) AS closing 
FROM (
    SELECT d.*, 
     TO_DATE(year || month, 'YYYYMM') AS dt 
    FROM data d 
) t 
ORDER BY dt 

:これも出力の名前が含まれます

SELECT t.*, 
     SUM(sales) OVER (PARTITION BY r_group ORDER BY year, month) - sales 
     AS opening, 
     SUM(sales) OVER (PARTITION BY r_group ORDER BY year, month) AS closing 
FROM (
    SELECT r_group, 
     year, 
     month, 
     SUM(sales) AS sales 
    FROM data 
    GROUP BY r_group, year, month 
) t 
ORDER BY year, month 

更新

+0

気にする列のロジックについて説明できますか? –

+0

for r_group = 'fruit' month = '05 'の開始値は、month =' 04 'の終了値でなければなりません。 r_group = 'fruit'の月= '05'の締め値は、月= '04'からの開始値+月= '05'の売上値でなければなりません。 – bytebiscuit

+0

この質問は非常に混乱しています.2つの答えがあり、正確な予測出力が得られましたが、その結果に興味はないようですが、集計前の中間ステップで表示されます。あなたはそれがあなたが期待していることを再考し、**のために[MCVE]を生成しなければなりません**(つまり、集計前にステップから何かを求めて、そのステップの期待出力を書き出し、 *その後のステップのために)。おそらく、この質問を放棄/削除し、新しい(より明確な)質問をする必要があります。 – MT0

答えて

1

グループR_GROUPYEARMONTHは、まず、分析クエリを使用することにより出力

ID NAME R_GROUP YEAR MONTH SALES DT   R_GROUP_MONTH_SALES OPENING CLOSING 
-- ---- --------- ---- ----- ----- ---------- ------------------- ------- ------- 
1 A fruit  2007 04  5 2007-04-01     104  0  104 
2 Z fruit  2007 04  99 2007-04-01     104  0  104 
3 A fruit  2008 05  10 2008-05-01     10  104  114 
4 B vegetable 2008 07  20 2008-07-01     20  0  20 

これで、このクエリの出力で任意の処理を実行できます。

たぶん、このような何か:

SELECT year, 
     month, 
     r_group, 
     MAX(r_group_month_sales) AS sales, 
     MAX(opening) AS opening, 
     MAX(closing) AS closing, 
     YOUR_THIRD_PARTY_AGGREGATION_FUNCTION(column_names) AS other 
FROM (
    -- insert the query above 
) 
GROUP BY year, month, r_group 
ORDER BY year, month 
+0

MT0に感謝します。しかし、この場合、私は名前を引き出す必要があります。年、月、r_groupは、年、月、名前、r_groupの上位に集計されます。 – bytebiscuit

+0

@bytebiscuitあなたの質問と予想される出力を 'name'カラムを含まないように更新できますか?そして私のクエリは、あなたが現在表示しているように期待される出力を与えます。 – MT0

+0

質問の編集を参照してください – bytebiscuit

1

代わりCURRENT ROWの前の行まで合計するPRECEDINGキーワードを使用することができます。

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 t.*, 
    coalesce(sum(sales) over (partition by r_group order by year, month rows between unbounded preceding and 1 preceding),0) opening, 
    sum(sales) over (partition by r_group order by year, month rows between unbounded preceding and current row) closing 
from (
    select year, month, r_group, sum(sales) sales 
    from data 
    group by year, month, r_group 
) t 
order by 3,1,2; 

year month r_group  sales opening closing 
--------------------------------------------------- 
2007 04  fruit  104  0  104 
2008 05  fruit  10  104  114 
2008 07  vegetable 20  0  20 
+0

MT0の答えと同じです。名前はインナーセレクトにも含める必要があります。さもなければ、詳細(すなわち、名前)まで掘り下げることができません。 – bytebiscuit

+0

@bytebiscuit「詳細まで掘り下げられる」という意味を説明してください。あなたはあなたの質問でクエリの出力で 'NAME'カラムを選択していないので、ドリルダウンすることはできません。 – MT0

+0

このクエリは、年、月、名前、r_group、オープン、クローズの詳細バージョンをデータベースに入力し、分析ツール(サードパーティ)を使用して集計を使用して、r_group上で集計します。しかし、年、月、名前、r_groupの詳細が存在する必要があります – bytebiscuit