2013-09-25 35 views
1

我正在处理这个特别复杂的问题(至少对我来说,如果你是数学极客,你不认为我!)问题。使用Oracle Analytics改进复杂的SQL查询

我基本上有两件事记录了当前库存水平是什么以及库存中或库存中的所有库存变动列表。我试图将这两部分结合起来,让我有能力在过去一年的任何时候了解特定对象的库存水平。

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 

所以之后,我有我似乎无法绕到我头上的几个问题。

首先 - 在第二个声明中,它返回一个365天的列表,当天所选对象的移动以及它的历史库存水平,我似乎无法让对象ID出现在每一行中。

第二 - 我很乐意能够运行这个程序,以便每天为每个对象提供365天的运动,并为当天的相应库存水平。我认为这必须包括比我目前拥有的更好的Oracle Analytics的理解。

任何帮助将不胜感激。

回答

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子句您解析函数:

​​