0
 select year, 
        month ,
        d.PROD_ID, 
        T.CUSTOMER_ID,
        SUM(CASE WHEN D.OP_TYPE = 1 THEN d.qty END)    EARNED,
        SUM(CASE WHEN D.OP_TYPE = 2 THEN d.qty END)    SPEND
FROM TXN_HEADER T  , 
     TXN_DETAIL d , 
     CUSTOMER A,
     PRODUCT e 
WHERE T.AMOUNT > 0 
AND   A.TYPE  =  0
AND   T.CUSTOMER_ID = A.CUSTOMER_ID
AND   T.TXN_PK = D.TXN_PK 
and   d.PROD_ID = e.PROD_ID
and   e.unit = 0
group by year, month ,d.PROD_ID, T.CUSTOMER_ID
ORDER BY 1,2,3,4 

出力は次のとおりです(ここでは、クエリによって生成された開閉ではありませんが、クエリからのものである必要があります)

YEAR MONTH PROD CUSTOMER OPENING EARNED SPEND CLOSING 
---- ----- ---- -------- ------- ------ ----- -------
2012     8  548    12033       0      8     2       6
2012     9  509    12033       0     24     0      24
2012     9  509    12047       0     14     0      14
2012     9  548    12033       6      1     0       7
2012     9  548    12047       0      1     0       1

上記のように出力を生成する必要がありました。ここで、PROD_ID、CUSTOMER_ID に関して、前の最終残高が動的に開始として取り込まれ、月ごと、顧客ごと、製品ごとに最終残高 (開始 + 獲得支出) を計算する必要があります。SQLで書くことは可能ですか、それともPL/SQLに移行する必要がありますか?

4

2 に答える 2

1

製品と顧客が混在しないように、partition 句に PROD_ID と CUSTOMER_ID を指定して分析を使用します。

WITH
MONTHLY_BALANCE AS
(
  SELECT
    YEAR,
    MONTH,
    D.PROD_ID,
    T.CUSTOMER_ID,
    SUM(CASE WHEN D.OP_TYPE = 1 THEN D.QTY ELSE NULL END) EARNED,
    SUM(CASE WHEN D.OP_TYPE = 2 THEN D.QTY ELSE NULL END) SPEND,
  FROM TXN_HEADER T
  JOIN CUSTOMER A 
  ON    T.CUSTOMER_ID = A.CUSTOMER_ID
  JOIN TXN_DETAIL D
  ON    T.TXN_PK = D.TXN_PK
  JOIN PRODUCT E
  ON    D.PROD_ID = E.PROD_ID
  WHERE T.AMOUNT > 0
  AND   A.TYPE = 0
  AND   E.UNIT = 0
  GROUP BY YEAR, MONTH, D.PROD_ID, T.CUSTOMER_ID
)
SELECT
  YEAR,
  MONTH,
  PROD_ID,
  CUSTOMER_ID,
  SUM(NVL(EARNED, 0) - NVL(SPEND, 0)) OVER(PARTITION BY PROD_ID, CUSTOMER_ID ORDER BY YEAR, MONTH ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) OPENING,
  EARNED,
  SPEND,
  SUM(NVL(EARNED, 0) - NVL(SPEND, 0)) OVER(PARTITION BY PROD_ID, CUSTOMER_ID ORDER BY YEAR, MONTH ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT_ROW) CLOSING
FROM MONTHLY_BALANCE
ORDER BY 1, 2, 3, 4
于 2012-09-19T17:49:26.273 に答える
0

あなたのCASEニーズELSE

CASE WHEN D.OP_TYPE = 1 THEN d.qty ELSE 0 END

else がなければ、is not equal toと anything+ =のときCASEに返されます。満足していない場合は返されるため、それらの列には何も表示されません。NULLD.OP_TYPE1NULLNULLWHENNULL

OPENING と CLOSING を計算して取得するには、や などの分析関数を使用できます。LEADLAG

Select year,month,prod_id,customer_id,
       LAG(closing,1,0) OVER (order by year,month,prod_id,customer_id) as opening,
       earned,spend
      ,(LAG(closing,1,0) OVER (order by year,month,prod_id,customer_id)+closing) as closing
from (WITH temp AS (select year, 
                           month ,
                           d.PROD_ID, 
                           T.CUSTOMER_ID,
                           0 OPEN,
                          SUM(CASE WHEN D.OP_TYPE = 1 THEN d.qty END)    EARNED,
                          SUM(CASE WHEN D.OP_TYPE = 2 THEN d.qty END)    SPEND,
                          0 CLOSE
                     FROM TXN_HEADER T  , 
                          TXN_DETAIL d , 
                          CUSTOMER A,
                          PRODUCT e 
                    WHERE T.AMOUNT > 0 
                      AND   A.TYPE  =  0
                      AND   T.CUSTOMER_ID = A.CUSTOMER_ID
                      AND   T.TXN_PK = D.TXN_PK 
                      and   d.PROD_ID = e.PROD_ID
                      and   e.unit = 0
                     group by year, month ,d.PROD_ID, T.CUSTOMER_ID
                     ORDER BY 1,2,3,4)
   SELECT year,month,prod_id,customer_id,open,earned,spend,(open+earned-spend) as closing
     from temp);
于 2012-09-19T14:57:35.917 に答える