当前位置:  数据库>oracle

Oracle数据分摊问题解析

    来源: 互联网  发布时间:2017-05-07

    本文导语: 经常会碰到,由于业务需要,需要将某种汇总的数据按照一定的原则分摊给一堆数据。其实,如果逻辑清晰的话,这类型的程序还是比较好些的。本文重点是如果用简单的程序实现这种效果,而且不容易分摊分错。 所有的分摊...

经常会碰到,由于业务需要,需要将某种汇总的数据按照一定的原则分摊给一堆数据。
其实,如果逻辑清晰的话,这类型的程序还是比较好些的。
本文重点是如果用简单的程序实现这种效果,而且不容易分摊分错。

所有的分摊问题,首先必须要搞清楚以下几点问题:
1 首要的,要确定 什么东西,多少数量 分摊给什么东西?举个形象的例子,一桶沙子分摊给一些瓶子。
2 分摊的先后原则。上面的例子,一桶沙子分摊给一些瓶子,那瓶子的被分摊顺序是什么样子的?沙子先给哪个瓶子?要先确定清楚。

说得好像有点麻烦,举个例子说明。
最近接到的一个需求:
PO入库的时候,批次可能重复输入,所以入库之后,库存已经汇总在一起了。然后用户对(汇总的)库存进行消耗(就是杂发)。
现在需要有个报表可以知道:按照先进先出的原则,区分用户的一段期间内的消耗数量 对应的是那笔入库单号。


备注:假设下面的数量对应都是主单位。

7.1 入库单R1  料号A 批次P1 接收入库 400
7.3 入库单R2  料号A 批次P1 接收入库 300
这时候,P1批次库存共 700
-------消耗(杂发)明细
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个瓶子里面。



装沙规则:
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= 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,因为根据黑色沙子的使用情况判断后面是否要退出瓶子的循环。
           L_CURR_PERIOD_QTY := 0;
         END IF;
         L_PRE_PERIOD_QTY:= 0;
       END IF;
        N := N+1;
        ----当黑色沙子用完的时候,要退出循环。因为沙子数量可能很少,但是瓶子很多。。。没必要再循环下去了。
        IF L_CURR_PERIOD_QTY


    
 
 

您可能感兴趣的文章:

  • linux下oracle的自启动脚本解析
  • oracle SQL解析步骤小结
  • 解析mysql与Oracle update的区别
  • 细化解析Oracle 10g STATSPACK的新功能
  • 深入解析Oracle参数及参数文件
  • Oracle数据库安装配置流程示例详细解析
  • Oracle中DBMS_SQL解析SQL语句的流程
  • [Oracle] RAC 之 - 负载均衡深入解析
  • Oracle数据库安全性管理基本措施实例解析
  • 解析Oracle查询和删除JOB的SQL
  • 解析jdbc处理oracle的clob字段的详解
  • 职场专家解析Oracle认证门道
  • oracle 索引不能使用深入解析
  • oracle的rownum深入解析
  • 解析如何查看Oracle数据库中某张表的字段个数
  • Oracle row_number() over()解析函数高效实现分页
  • 解析学习Oracle架构所应了解的基础知识
  • Oracle基本查询过滤排序示例解析
  • Oracle硬解析和软解析的区别分析
  • 解析Oracle中多表级联删除的方法
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • Oracle 数据库(oracle Database)Select 多表关联查询方式
  • oracle数据库导出和oracle导入数据的二种方法(oracle导入导出数据)
  • oracle中如何把表中具有相同值列的多行数据合并成一行
  • Oracle 数据库开发工具 Oracle SQL Developer
  • Oracle数据库(Oracle Database)体系结构及基本组成介绍
  • 请问大家用oracle数据库, 用import oracle.*;下的东西么? 还是用标准库?
  • ORACLE数据库常用字段数据类型介绍
  • 怎样调出ORACLE数据库中的数据,该如何连接?
  • Oracle 数据库(oracle Database)性能调优技术详解
  • 用JDBC连接Oracle数据库时,如何向数据库中写日期型数据(格式)?谢了!
  • 关于JDBC连接Oracle数据库,是否必须有Oracle客户端
  • linux上安装oracle 数据库后,是否能写shell程序实现数据库的自动启动。
  • win2000+jbuilder6+oracle817编出的程序,在win2000下执行很好,在win98下却访问不了oracle数据库
  • jsp文件上传smartupload到oracle数据库中没有longblob的数据类型如何处理的?
  • 将Oracle 8i数据成功移植Oracle 10g的方法
  • Oracle收购TimesTen 提高数据库软件性能
  • 我从JSP页将数据插入到oracle数据库中,为何汉字插入后数据库中显示为乱码呢?
  • Oracle数据库恢复后心得
  • 紧急求救:对Oracle数据库中long 型数据进行模糊查询 如何查?
  • Linux下Oracle数据库,dbstart持续不动,数据库无法启动解决
  • 卸载oracle数据库
  • Oracle 12c发布简单介绍及官方下载地址
  • 在linux下安装oracle,如何设置让oracle自动启动!也就是让oracle那个服务自动启动,不是手动的
  • oracle 11g最新版官方下载地址
  • 请问su oracle 和su - oracle有什么不同?
  • 操作系统 iis7站长之家
  • 虚拟机装Oracle R12与Oracle10g
  • Oracle 10g和Oracle 11g网格技术介绍
  • Oracle EBS R12 支持 Oracle Database 11g
  • ORACLE日期相关操作
  • SCO unix下安装oracle,但没有光盘,请大家推荐一个oracle下载站点(unix版本的)。谢谢!!!!


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,