指标引擎(jraf)

预处理


  1. MO_KPI_INFO中需要计算的指标放入临时表CA_MO_KPI_INFO
  2. 将机构、人员历史表中的数据放入临时表CA_TMP_DEPTCA_TMP_MANAGER
  3. 解析每个指标的配置KpiConfPretreat
    1. 基础指标
      1. 获取统计规则与自定义统计规则,获取指标模型
      2. 将当前指标的口径项和统计规则中的字段替换成加工列的字段
      3. 将口径项和统计规则中的参数(例如:$$DATA_DATE$$)替换成SQL的形式(例如:DATE ‘2020-01-01’)
      4. 校验口径项与统计规则中的字段与指标模型中的来源表中字段是否正确
      5. 存入临时指标表CA_TMP_KPI_INF
    2. 派生指标、手工指标,直接存入临时指标表CA_TMP_KPI_INFO
  4. 初始化机构参数KpiParamPretreat,将MO_PAR_INFO_ORG、MO_PAR_DETAIL_ORG中的数据放入临时表CA_TMP_PARA_ORG中
  5. 初始化汇率参数KpiExchPretreat

解析


  1. 解析基础指标、手工指标
    1. 将该指标信息初始化为任务
    2. 如果该指标是扩展指标,则查询出该指标对应的主指标,设置为该指标的依赖任务对象
  2. 解析派生指标
    1. 将该指标信息初始化为任务
    2. 如果该指标是扩展指标,则查询出该指标对应的主指标,设置为该指标的依赖任务对象
    3. 解析该派生指标引用的指标,设置为依赖任务
  3. 该指标任务插入CA_CTL_KPI_TASK表中,依赖任务插入CA_CTL_KPI_TASK_DEPEND表中

计算


  1. 重新跑当前批次中错误的指标任务
  2. 循环层级依赖关系
    1. 第一次查询没有被依赖的指标进行执行,提交任务到线程池队列
    2. 后面查询有依赖的指标,判断依赖的指标是否已经全部完成,如果全部执行完成,提交到线程池队列
    3. 监听完成情况
      1. 循环监听每个线程,判断线程是否完成
      2. 已完成的线程,获取执行结果,更新CA_CTL_KPI_TASK表中的状态
      3. 计算
        1. 主指标—基础指标(机构):
          1. 拼接SQL,获取指标值
            SELECT DATA_DATE,ORG_NO,KPI_CODE,AREA_NO,EXCH_TYPE,SUM(口径列) FROM src_data_table
            WHERE DATA_DATE <= DATE 'DATA_DATE' AND DATA_DATE >=月初 AND AREA_NO = '' AND 统计规则
            GROUP BY ORG_NO,AREA_NO
          2. 按机构汇总指标值,将下级机构的指标值累计,替换成父级机构的指标值 > 不需要按照从最底层开始向上汇总吗?
          3. 月、季、年等周期性指标需要累计前一天的指标值,将前一天的指标值进行累加。
          4. 查询出目标值,统计出目标值字段
          5. 插入PI_ORG_KPI
        2. 主指标—基础指标(人员):
          1. 拼接SQL,获取指标值
            SELECT DATA_DATE,MANAGER_NO,ORG_NO,KPI_CODE,AREA_NO,EXCH_TYPE,SUM(口径列) FROM src_data_table
            WHERE DATA_DATE <= DATE 'DATA_DATE' AND DATA_DATE >=月初 AND AREA_NO = '' AND 统计规则
            GROUP BY AREA_NO,MANAGER_NO,ORG_NO
          2. 月、季、年等周期性指标需要累计前一天的指标值,将前一天的指标值进行累加。
          3. 先将指标数据插入到PI_ORG_KPI_PERSON_DETAIL表中,再将数据汇总到PI_ORG_KPI_PERSON表中 > DETAIL表有什么用?汇总好像是唯一的
        3. 主指标—派生指标
          1. 派生指标中有函数,则直接拼接SQL
            SELECT DATE ''   AS dataDate,
            k1.managerNo,
            k1.orgNo,
            ''        as kpiCode,
            --   k1.areano as areaNo,
            coalesce(k1.kpiValue + k2.kpiValue, 0) as kpiValue
            from (
            select m.manager_no as managerNo, m.org_no as orgNo, k.kpi_value as kpiValue, k.kpi_value_us as kpiValueUS
            FROM ca_tmp_manager m
            INNER JOIN PI_ORG_KPI_PERSON k ON m.manager_no = k.manager_no and m.area_no = k.area_no
            and m.flow_code = ''
            WHERE k.kpi_code = ''
            and k.data_date = DATE ''
            AND k.manager_no = ''
            ) k1 --第一个指标的值
            left join
            (
            select m.manager_no as managerNo, m.org_no as orgNo, k.kpi_value as kpiValue, k.kpi_value_us as kpiValueUS
            FROM ca_tmp_manager m
            INNER JOIN PI_ORG_KPI_PERSON k ON m.manager_no = k.manager_no and m.area_no = k.area_no
            and m.flow_code = ''
            WHERE k.kpi_code = ''
            and k.data_date = DATE ''
            AND k.manager_no = ''
            ) k2 on k1.orgNo = k2.orgNo and k1.managerNo = k2.managerNo  --第二个指标的值
          2. 解析派生指标规则
            1. 解析CASE WHEN
            2. 简化指标规则—将K(9900B00001A0100)+K(9900B00002A0100)简化为K1+K2
          3. 将计算规则转换成二叉树,递归计算
            1. 将最小括号内的表达式转换成一个二叉树子树,依次往外面进行拓展,最终形成一个二叉树
            2. 根据二叉树的根节点,找到左节点与右节点,递归遍历得到左右节点的值
            3. 如果该叶子节点是一个指标,则查询出对象的指标集合;如果该叶子节点是一个参数,则替换成对应的值
            4. 将左节点与右节点的值,进行计算
              1. 如果两个节点都是指标,则根据对象进行计算
              2. 如果一个节点是指标,一个节点是数值,则所有对象的指标值与数值进行计算
              3. 如果二个节点都是数字,则直接进行计算
            5. 返回根节点计算得到的值
          4. 判断结果是数字还是指标,如果是数值,则所有对象的指标值都为该值,如果是指标值,则每个对象都有对应的指标值
          5. 月、季、年等周期性指标需要累计前一天的指标值,将前一天的指标值进行累加。
          6. 查询出目标值,统计出目标值字段
          7. 插入PI_ORG_KPIPI_ORG_KPI_PERSON

            四则运算的实现:

            1. 二叉树:实现比较复杂

            2. 栈:实现简单

            3. jexl表达式

        4. 主指标—手工指标
          1. 拼接SQL,获取指标值
            SELECT DATA_DATE,ORG_NO,KPI_CODE,AREA_NO,EXCH_TYPE,KPI_VALUE FROM INPUT_DATA_TABLE
            WHERE START_DATE <= DATE 'DATA_DATE' AND END_DATE >= DATE 'DATA_DATE' AND AREA_NO = '' AND KPI_CODE = ''
          2. 查询出目标值,统计出目标值字段
          3. 插入PI_ORG_KPI
        5. 附属指标
          1. 根据附属属性,获取对应的日期(如较上年:上年末)
          2. 拼接SQL
            SELECT A.DATA_DATE AS DATADATE, A.ORG_NO AS ORGNO, '附属指标编号' AS KPI_CODE, A.AREA_NO AS AREANO,
            A.KPI_VALUE-COALESCE(B.KPI_VALUE,0) AS KPIVALUE
            FROM (
            SELECT * FROM SRC_TABLE WHERE DATA_DATE = DATE 'DATA_DATE' AND KPI_CODE = '主指标编号') A
            LEFT JOIN
            (SELECT * FROM SRC_TABLE WHERE DATA_DATE = DATE 'ATTR_DATE' AND KPI_CODE = '主指标编号') B
            ON A.ORG_NO = B.ORG_NO
            1. 增幅(A-B)/B,增量A-B
            2. 较基数
            3. 较目标
          3. 查询出目标值,统计出目标值字段
          4. 插入PI_ORG_KPI
      4. 汇总到宽表,加上上月末、上季末指标值等字段。