• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當前位置: 首頁 - 科技 - 知識百科 - 正文

    Oracle數據分攤問題解析

    來源:懂視網 責編:小采 時間:2020-11-09 09:42:45
    文檔

    Oracle數據分攤問題解析

    Oracle數據分攤問題解析:經常會碰到,由于業(yè)務需要,需要將某種匯總的數據按照一定的原則分攤給一堆數據。 其實,如果邏輯清晰的話,這類型的程序還是比較好些的。 本文重點是如果用簡單的程序實現這種效果,而且不容易分攤分錯。 所有的分攤問題,首先必須要搞清楚以下幾點問題:
    推薦度:
    導讀Oracle數據分攤問題解析:經常會碰到,由于業(yè)務需要,需要將某種匯總的數據按照一定的原則分攤給一堆數據。 其實,如果邏輯清晰的話,這類型的程序還是比較好些的。 本文重點是如果用簡單的程序實現這種效果,而且不容易分攤分錯。 所有的分攤問題,首先必須要搞清楚以下幾點問題:

    經常會碰到,由于業(yè)務需要,需要將某種匯總的數據按照一定的原則分攤給一堆數據。 其實,如果邏輯清晰的話,這類型的程序還是比較好些的。 本文重點是如果用簡單的程序實現這種效果,而且不容易分攤分錯。 所有的分攤問題,首先必須要搞清楚以下幾點問題: 1

    經常會碰到,由于業(yè)務需要,需要將某種匯總的數據按照一定的原則分攤給一堆數據。
    其實,如果邏輯清晰的話,這類型的程序還是比較好些的。
    本文重點是如果用簡單的程序實現這種效果,而且不容易分攤分錯。

    所有的分攤問題,首先必須要搞清楚以下幾點問題:
    1 首要的,要確定 什么東西,多少數量 分攤給什么東西?舉個形象的例子,一桶沙子分攤給一些瓶子。
    2 分攤的先后原則。上面的例子,一桶沙子分攤給一些瓶子,那瓶子的被分攤順序是什么樣子的?沙子先給哪個瓶子?要先確定清楚。

    說得好像有點麻煩,舉個例子說明。
    最近接到的一個需求:
    PO入庫的時候,批次可能重復輸入,所以入庫之后,庫存已經匯總在一起了。然后用戶對(匯總的)庫存進行消耗(就是雜發(fā))。
    現在需要有個報表可以知道:按照先進先出的原則,區(qū)分用戶的一段期間內的消耗數量 對應的是那筆入庫單號。

    備注:假設下面的數量對應都是主單位。

    7.1 入庫單R1 料號A 批次P1 接收入庫 400
    7.3 入庫單R2 料號A 批次P1 接收入庫 300
    這時候,P1批次庫存共 700
    -------消耗(雜發(fā))明細
    7.10 消耗P1 100
    7.12 消耗P1 200
    8.10 消耗P1 200
    8.13 消耗P1 100
    8.20 消耗P1 50
    9.20 消耗P1 50


    如果查詢報表的日期選擇的是:8.1~8.31
    8.1號 之前共消耗100+200=300
    8.1~8.31號 之內一共消耗:200+100+50=350

    所以核心問題是要將350如何分攤在R1和R2里面。
    要實現的分攤效果:
    入庫總數 之前消耗的分攤 期間內消耗的分攤
    R1 400 300 100
    R2 300 0 250

    所以,結果是,報表是:8.1~8.31
    一共消耗350,對應入庫單的消耗情況:
    R1消耗100
    R2消耗250

    實現邏輯:
    你可以假想,現在有2個沙桶,
    紅色的沙桶裝的沙子是 之前消耗的分攤 的數量
    黑色的沙桶裝的沙子是 期間內消耗的分攤 的數量
    每張入庫單就是一個瓶子,所以共有2個瓶子,R1和R2。現在是如何將 紅色的沙子 和 黑色的沙子 裝到這2個瓶子里面。

    裝沙規(guī)則:
    1 用沙子的順序:先用 紅色的沙子,用完之后,再用黑色的沙子。
    2 裝瓶子的順序:按照先進先出的原則,必須先裝瓶子R1,再裝R2.



    DECLARE
    L_PRE_PERIOD_QTY NUMBER; ---期間前的匯總消耗量 ---之前消耗的分攤 的數量---紅色的沙子
    L_CURR_PERIOD_QTY NUMBER ; --本期的匯總消耗量--期間內消耗的分攤 的數量---黑色的沙子
    ----裝的結果用記錄類型存下來,因為后面要用到。
    TYPE shipment_consume_Rec_Type IS RECORD
    (
    SHIPMENT_LINE_ID NUMBER
    , PRIMARY_QUANTITY NUMBER
    , consume_pre_qty NUMBER
    , consume_curr_qty NUMBER
    );
    TYPE shipment_consume_Tbl_Type IS TABLE OF shipment_consume_Rec_Type
    INDEX BY BINARY_INTEGER ;
    L_shipment_consume_Tbl shipment_consume_Tbl_Type;
    N NUMBER;
    BEGIN
    ----1 首先要算出紅色的沙子和黑色的沙子的總數量,就是有多少數量可分攤。
    SELECT nvl(sum(case when MMT.transaction_date < :P_F_START_DATE then
    ABS(NVL(MTLN.PRIMARY_QUANTITY,0))
    else
    0
    end ),0) PRE_PERIOD_QTY,
    nvl(sum(case when MMT.transaction_date >= :P_F_START_DATE then
    ABS(NVL(MTLN.PRIMARY_QUANTITY,0))
    else
    0
    end ),0) CURR_PERIOD_QTY
    INTO L_PRE_PERIOD_QTY,L_CURR_PERIOD_QTY
    FROM MTL_MATERIAL_TRANSACTIONS MMT
    ,MTL_TRANSACTION_LOT_NUMBERS MTLN
    WHERE MMT.TRANSACTION_ID = MTLN.TRANSACTION_ID
    AND MMT.TRANSACTION_TYPE_ID = 74
    AND MMT.TRANSACTION_ACTION_ID = 6
    AND MMT.OWNING_TP_TYPE = 1 ---所有權轉出的(寄售供應商的庫存)
    ---
    AND MMT.ORGANIZATION_ID = 103
    AND MMT.INVENTORY_ITEM_ID = 11783561
    AND MTLN.LOT_NUMBER = 'P0000001'
    AND MMT.transaction_date<=:P_F_END_DATE;
    DBMS_OUTPUT.PUT_LINE('L_PRE_PERIOD_QTY:'||L_PRE_PERIOD_QTY||' -L_CURR_PERIOD_QTY:'||L_CURR_PERIOD_QTY);
    N := 1;

    -----2 分攤主邏輯。
    FOR REC_SHIPMENT_LINE IN (
    -----瓶子(入庫單)的游標
    SELECT MMT.ORGANIZATION_ID
    ,MMT.INVENTORY_ITEM_ID
    ,MTLN.LOT_NUMBER
    ,MTLN.TRANSACTION_DATE
    ,RT.SHIPMENT_HEADER_ID
    ,RT.SHIPMENT_LINE_ID
    ,MTLN.PRIMARY_QUANTITY
    FROM MTL_TRANSACTION_LOT_NUMBERS MTLN, MTL_MATERIAL_TRANSACTIONS MMT,RCV_TRANSACTIONS RT
    WHERE MTLN.TRANSACTION_ID = MMT.TRANSACTION_ID
    AND RT.TRANSACTION_ID = MMT.RCV_TRANSACTION_ID
    AND MMT.TRANSACTION_TYPE_ID = 18
    AND MMT.TRANSACTION_SOURCE_TYPE_ID = 1
    AND XYG_PO_PKG.CHECK_PO_LINE_CONSIGN(RT.PO_LINE_ID) = 'Y'
    AND MMT.ORGANIZATION_ID = 103
    AND MMT.INVENTORY_ITEM_ID = 11783561
    AND MTLN.LOT_NUMBER = 'P0000001'
    ORDER BY MTLN.TRANSACTION_DATE,MMT.TRANSACTION_ID) LOOP
    ---2.1 優(yōu)先消耗期初之前的耗料數量,就是先用紅色的沙子的數量。
    IF L_PRE_PERIOD_QTY >= REC_SHIPMENT_LINE.PRIMARY_QUANTITY THEN ---當紅色沙子的數量大于瓶子的容量的時候。
    L_shipment_consume_Tbl(N).SHIPMENT_LINE_ID :=REC_SHIPMENT_LINE.SHIPMENT_LINE_ID;
    L_shipment_consume_Tbl(N).PRIMARY_QUANTITY :=REC_SHIPMENT_LINE.PRIMARY_QUANTITY;
    ----消耗紅沙的數量就是瓶子的容量。
    L_shipment_consume_Tbl(N).consume_pre_qty :=REC_SHIPMENT_LINE.PRIMARY_QUANTITY;
    L_shipment_consume_Tbl(N).consume_curr_qty :=0;
    ----期初數量就是剩下要分配的數量。因為紅色沙子已經被消耗掉一部分了。
    L_PRE_PERIOD_QTY :=L_PRE_PERIOD_QTY-REC_SHIPMENT_LINE.PRIMARY_QUANTITY;
    ELSE ---當紅色沙子的數量小于瓶子容量的時候
    L_shipment_consume_Tbl(N).SHIPMENT_LINE_ID :=REC_SHIPMENT_LINE.SHIPMENT_LINE_ID;
    L_shipment_consume_Tbl(N).PRIMARY_QUANTITY :=REC_SHIPMENT_LINE.PRIMARY_QUANTITY;
    ----瓶子裝 紅色沙子的數量就是紅色沙子的數量了
    L_shipment_consume_Tbl(N).consume_pre_qty :=L_PRE_PERIOD_QTY;

    ----這時候已經用完紅色沙子了,開始用黑色沙子了-----
    ---2.2 當黑色沙子數量大于瓶子 可用的容量 的時候。
    IF L_CURR_PERIOD_QTY > (REC_SHIPMENT_LINE.PRIMARY_QUANTITY - L_PRE_PERIOD_QTY) THEN
    ---該瓶子 裝黑色沙子的數量 就是 瓶子的可用容量。
    L_shipment_consume_Tbl(N).consume_curr_qty := REC_SHIPMENT_LINE.PRIMARY_QUANTITY - L_PRE_PERIOD_QTY;
    ---本次還有多少數量需要被下一個單號分攤,就是確定剩下還有多少黑色沙子可用。
    L_CURR_PERIOD_QTY := L_CURR_PERIOD_QTY - L_shipment_consume_Tbl(N).consume_curr_qty;
    ELSE
    ----當黑色沙子數量 小于或者等于 瓶子的可用容量的時候
    -----該瓶子裝黑色沙子的數量就是 瓶子的可用容量。
    L_shipment_consume_Tbl(N).consume_curr_qty := L_CURR_PERIOD_QTY;
    -----黑色沙子用完咯!~~一定要賦值0,因為根據黑色沙子的使用情況判斷后面是否要退出瓶子的循環(huán)。
    L_CURR_PERIOD_QTY := 0;
    END IF;
    L_PRE_PERIOD_QTY:= 0;
    END IF;
    N := N+1;
    ----當黑色沙子用完的時候,要退出循環(huán)。因為沙子數量可能很少,但是瓶子很多。。沒必要再循環(huán)下去了。
    IF L_CURR_PERIOD_QTY <= 0 THEN
    EXIT;
    END IF;
    END LOOP;

    ---顯示裝的結果。
    FOR I IN 1..L_shipment_consume_Tbl.COUNT LOOP
    DBMS_OUTPUT.PUT_LINE(L_shipment_consume_Tbl(I).SHIPMENT_LINE_ID
    ||'-'|| L_shipment_consume_Tbl(I).PRIMARY_QUANTITY
    ||'-'|| L_shipment_consume_Tbl(I).consume_pre_qty
    ||'-'|| L_shipment_consume_Tbl(I).consume_curr_qty
    );

    END LOOP;
    END;

    /*
    ---例如:
    L_PRE_PERIOD_QTY:0 -L_CURR_PERIOD_QTY:2020.2
    18467366-1605.5-0-1605.5
    18633076-5014.7-0-414.7

    */

    聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    Oracle數據分攤問題解析

    Oracle數據分攤問題解析:經常會碰到,由于業(yè)務需要,需要將某種匯總的數據按照一定的原則分攤給一堆數據。 其實,如果邏輯清晰的話,這類型的程序還是比較好些的。 本文重點是如果用簡單的程序實現這種效果,而且不容易分攤分錯。 所有的分攤問題,首先必須要搞清楚以下幾點問題:
    推薦度:
    標簽: 數據 問題 解析
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 国产精品国产三级国产普通话| 国产精品1024视频| 一区二区三区四区精品视频| 在线亚洲精品福利网址导航| 国产精品户外野外| 久久久久国产精品| 精品三级AV无码一区| 亚洲欧美日韩国产精品影院| 国产精品欧美久久久久无广告| 国产精品美女久久久| 精品国产乱码一区二区三区| 中文字幕久久精品| 日韩蜜芽精品视频在线观看| 国产精品成人久久久久三级午夜电影 | 久久久精品免费国产四虎| 久久亚洲私人国产精品vA | 国产精品成人69XXX免费视频| 国产精品免费观看调教网| 亚洲AV无码国产精品色午友在线| 无码精品人妻一区| 久久久精品波多野结衣| 国产精品videossex白浆| 99久免费精品视频在线观看| 亚洲欧洲国产日韩精品| 日本一区精品久久久久影院 | xxx国产精品视频| 精品福利视频一区二区三区 | 午夜精品一区二区三区免费视频| 日本欧美国产精品第一页久久| 精品久久人人妻人人做精品| jizz国产精品| 中文字幕精品一区影音先锋| 欧美精品国产精品| 欧美精品在线一区| 999精品色在线播放| 99在线精品免费视频| 国产精品久久久99| 狠狠色伊人久久精品综合网| 国产亚洲精品自在线观看| 精品久久国产一区二区三区香蕉| 精品人妻少妇一区二区三区|