数据库时间段合并
项目中遇到一个有意思的业务需求,涉及到时间区间的合并与拆分;简化描述一下:
假定系统中有两类用户:甲方,暂称债务人; 乙方,暂称为债权人
债务人和债权人之间可以生成许多实体对象;若当债务人与指定的债权人签订协议后,就意味着双方存在了关系,此时就要求对关系双方的实体对象打上标记,标记分三种,分别为:当前、已终止、没关系(空)。 大概就是这个意思,当然实际中还有其它细节,这里就捡主要意思说。
补充说明一下:因债务人针对每一笔协议可选择多个债权人,为体现其一对多关系,所以设计了两张表,协议表和协议-债权人表。其中,协议可以是未来生效的协议,并且债务人针对同一债权人可以上传多笔协议,能自由维护债权人列表(即:添加和剔除债权人)。
库表:
协议表(b_refactor_finance)
Name |
Type |
Comments
扫描二维码关注公众号,回复:
1190030 查看本文章
|
Refactorfincode |
Varchar2(28) |
协议编号 |
Debtororgcode |
Varchar2(30) |
债务人 |
Begindate |
Date |
协议起始日 |
Enddate |
Date |
协议到期日 |
Createddate |
Date |
创建时间 |
协议-债权人表(b_refactorfin_creditors)
Name |
Type |
Comments |
Id |
Number(27) |
序号 |
Refactorfincode |
Varchar2(28) |
协议编号 |
Creditororgcode |
Varchar2(30) |
债权人 |
Status |
Varchar2(1) |
用户状态(0-启用,1-停用) |
Createddate |
Date |
启用时间 |
Stoppeddate |
Date |
停用时间 |
初步想法,应该都趋向于采用即时查询;也就是当需要展示标记时,即时判断实体的生成时间是否落在某笔协议内,然后再判断协议是否当前有效(即当前时间位于协议起始之间) 就能够把三种标记区分开来。
但实际业务中可能存在另一种情形(如图一):
图一
假定当前时间为10月,双方第一笔协议起始时间为1 - 6月;在这期间债权人上传了一笔账款,从当前来看,此账款标识应为关系已终止;若又存在另一笔协议起始时间为4 - 12月,此时双方关系的时段就应算这两笔协议时段的合并,即1 - 12月,账款标记为当前关系。也就是当协议时段存在重叠时,会导致关系时段被扩展,原打上的标记就不对了。
为解决此问题,需新加一张债务/债权人关系表,记录双方的关系区间。当协议相交时则合并;反之,协议终止则拆分。
库表:
债务人/债权人关系表(b_refactorfin_c_d)
Name |
Type |
Comments |
Id |
Number(27) |
序号 |
Debtororgcode |
Varchar2(30) |
债务人 |
Creditororgcode |
Varchar2(30) |
债权人 |
Begindate |
Date |
关系起始日 |
Enddate |
Date |
关系到期日 |
关系时段维护思路:(新增协议和协议终止实则为债权人被加入或移出协议的过程)
关系维护流程图
附件为Oracle过程代码