1

私はこの特に複雑な問題を扱っています (少なくとも私にとっては、あなたが数学オタクなら、私を判断しないでください!)。

基本的に、現在の在庫レベルの記録と、店舗内外のすべての在庫の動きのリストという 2 つのものを持っています。昨年の任意の時点での特定のオブジェクトの在庫レベルを理解できるように、2 つの部分を組み合わせようとしています。

SQL の最初の部分は、特定の店舗のすべてのオブジェクトの昨年のすべての在庫の動きと現在の在庫レベルを結合します。

SELECT OBJINCDE, 
       STOREINCDE, 
       TRUNC(STKMVTDTE) AS MOVEMENT_DATE, 
       --This CASE statement tells me if the stock was moved in or out
       CASE WHEN STKMVTINCDE IN (1, 2, 3, 5, 6, 8, 9, 11)  THEN 1 ELSE -1 END AS MOVEMENT

    FROM H_STK

    WHERE TRUNC(STKMVTDTE, 'MM') >= ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -12)  --in the last year
    AND STOREINCDE = 615  --A particular store

UNION ALL

--This statement looks at current levels and combines it with movements as a movement in on the date that the statement was run

SELECT OBJINCDE, 
       STOREINCDE, 
       TRUNC(SYSDATE) AS MOVEMENT_DATE, 
       STKQTY AS MOVEMENT                             

    FROM P_OBJSTORE                                

    WHERE (STKBRKQTY > 0 OR STKMAXQTY > 0)  --This just only picks objects that have a maximum or minimum listed don't judge the stock system either, I can't change that
    AND STOREINCDE = 615

したがって、基本的にすべての株式の動きとその日付のリストが返され、それをこのステートメントで使用します。

SELECT TO_CHAR(y.EACH_DAY, 'DD/MM/YYYY') AS EACH_DAY,
       x.OBJINCDE AS OBJINCDE,
       NVL(x.MOVEMENT, 0) AS MOVEMENT,
       SUM(NVL(x.MOVEMENT, 0)) OVER ( ORDER BY y.EACH_DAY DESC) AS STOCK_LEVEL  --Oracle analytics to put together a running total

FROM (SELECT OBJINCDE, MOVEMENT_DATE, SUM(MOVEMENT) AS MOVEMENT             
          FROM W_MIN_MAX_MOVEMENTS  
          WHERE OBJINCDE = 14419  --This is my selection of a particular object
          GROUP BY OBJINCDE, MOVEMENT_DATE
          HAVING SUM(MOVEMENT) <> 0
          ORDER BY MOVEMENT_DATE) x,
     (SELECT TRUNC(SYSDATE) - 365 + LEVEL AS EACH_DAY  --Just brings in each day for the last 365 days
          FROM DUAL
          WHERE ROWNUM <= 365
          CONNECT BY LEVEL = ROWNUM) y

WHERE x.MOVEMENT_DATE (+) = y.EACH_DAY

ORDER BY y.EACH_DAY DESC

その後、頭を包み込むことができないように見えるいくつかの問題があります。

最初-2番目のステートメントでは、365日のリスト、その日の選択されたオブジェクトの動き、および過去の在庫レベルを返します。オブジェクトIDをすべての行に表示することはできません。

第二に、これを実行して、その日の対応する在庫レベルですべてのオブジェクトの 365 日間の移動を取得できるようにしたいと考えています。これには、私が現在持っているよりも Oracle Analytics についての理解を深める必要があると思います。

どんな助けでも大歓迎です。

4

1 に答える 1

1

オブジェクトのリストが必要です。ストック ビューで個別のものを使用しますが、おそらく別の親テーブルの方が優れている可能性があります。

SELECT to_char(cal.each_day, 'dd/mm/yyyy') AS each_day,
       obj.objincde AS objincde,
       nvl(sto.movement, 0) AS movement,
       SUM(nvl(sto.movement, 0)) over(ORDER BY cal.each_day DESC) 
         AS stock_level --oracle analytics to put together a running total
  FROM (SELECT DISTINCT objincde
          FROM w_min_max_movements
         WHERE objincde = 14419 --this is my selection of a particular object
        ) obj
 CROSS JOIN (SELECT trunc(SYSDATE) - 365 + LEVEL 
                    AS each_day --just brings in each day for the last 365 days
               FROM dual
              WHERE rownum <= 365
             CONNECT BY LEVEL = rownum) cal
  LEFT JOIN (SELECT objincde, movement_date, SUM(movement) AS movement
               FROM w_min_max_movements
              GROUP BY objincde, movement_date
             HAVING SUM(movement) <> 0) sto 
         ON sto.movement_date = cal.each_day
        AND sto.objincde = obj.objincde 
 ORDER BY cal.each_day DESC

これにより、オブジェクト ID がすべての行に表示されます。

ちなみに、これからは ANSI 結合を使用するようにしてください。古いスタイルの結合は読みにくく、追加の制限があり、レガシー コードでのみサポートされています。新しいコードはすべて ANSI 結合を使用する必要があります。

すべてのオブジェクトのすべての日付を表示する場合は、句を削除して、分析関数に句WHEREを追加PARTITIONします。

SELECT to_char(cal.each_day, 'dd/mm/yyyy') AS each_day,
       obj.objincde AS objincde,
       nvl(sto.movement, 0) AS movement,
       SUM(nvl(sto.movement, 0)) 
         over(PARTITION BY obj.objincde ORDER BY cal.each_day DESC) 
         AS stock_level --oracle analytics to put together a running total
  FROM (SELECT DISTINCT objincde
          FROM w_min_max_movements) obj
 CROSS JOIN (SELECT trunc(SYSDATE) - 365 + LEVEL 
                    AS each_day --just brings in each day for the last 365 days
               FROM dual
              WHERE rownum <= 365
             CONNECT BY LEVEL = rownum) cal
  LEFT JOIN (SELECT objincde, movement_date, SUM(movement) AS movement
               FROM w_min_max_movements
              GROUP BY objincde, movement_date
             HAVING SUM(movement) <> 0) sto 
         ON sto.movement_date = cal.each_day
        AND sto.objincde = obj.objincde 
 ORDER BY cal.each_day DESC
于 2013-09-25T09:48:31.743 に答える