业务部门要求计算基金交易的手续费,包括申购/赎回/转换等操作,要考虑基金公司和代销机构的分成比例。大致业务规则如下:
--交易手续费计算,区分转换和非转换两种情形,关注手续费分割比例表t_mafee_divide_ratio
--分割指的是代销机构(如银行、券商)和基金公司之间的分成(比例在[0, 1]之间,表示代销机构的提成比例)
--交易费用=commission + agencyfee + stampduty + otherfare1 + otherfare2(佣金、过户费、印花税、后收费用、其它费用)
--基金资产=fundfare
--分成有可能是在包含基金资产或剔除基金资产之后(交易费用-基金资产)进行
--分成比例表大致信息为(distributorcode, fundcode, codeoftargetfund, busexplain, divideratio)
范例数据如
1. (004, 070001, 070009, 转出, 1.0000)
2. (004, 070001, NULL, 转出, 0.4000)
3. (004, 070001, NULL, 申购, 0.4000),对于非转换(申购/赎回等)业务,codeoftargetfund为空
现在问题是根据(distributorcode, fundcode, codeoftargetfund, busexplain)取对应的divideratio值。
对于转换业务要判断给定的codeoftargetfund是否能在表中查到,若查不到,则用NULL再去查一遍。
比如在上面范例中(004, 070001, 070009, 转出)能查出比例是1.0000,若(004, 070001, 070003, 转出)则应该查出(004, 070001, NULL, 转出, 0.4000)这条记录。
使用常规办法,必须写出两个单独的查询,笔者经过一番思考,根据业务逻辑,将两个查询二合一,弄成一块。其最大好处是更加复杂的查询能够用一段单独的SQL语句编写完成。
--查询1.1 转换有对应目标转出基金
select w.codeoftargetfund, w.divideratio
from t_mafee_divide_ratio w
where w.fundcode = '070001'
and w.distributorcode = '004'
and w.busexplain = '转出'
AND w.codeoftargetfund = '070009'
;
--查询1.2 转换无对应目标转出基金(使用通用)
select w.codeoftargetfund, w.divideratio
from t_mafee_divide_ratio w
where w.fundcode = '070001'
and w.distributorcode = '004'
and w.busexplain = '转出'
AND w.codeoftargetfund is null
;
--查询2 合并写法
SELECT x.codeoftargetfund, x.divideratio
FROM
(
--select nvl(w.codeoftargetfund, 'XXXXXX') codeoftargetfund, w.divideratio
select codeoftargetfund, w.divideratio
from t_mafee_divide_ratio w
where w.fundcode = '070001'
and w.distributorcode = '004'
and w.busexplain = '转出'
AND (w.codeoftargetfund = '070009' or w.codeoftargetfund is null)
ORDER BY w.codeoftargetfund -- NULL值升序时会排在最后
--ORDER BY nvl(w.codeoftargetfund, 'XXXXXX')
) x
WHERE rownum = 1 -- 只取出第一条记录
;