去除oracle时的一个问题解决历程

问题模拟场景简述:

首先,以前的oracle中有以下两张表:user_info,city_info

user_info: user_id, register_time, register_city(整型)

city_info: id, name, pid

city_info采用的是树形结构,根节点的pid为0,树的层级不确定,id从1开始,根节点为各个省份和直辖市

user_info中的register_city对应的是city_info的id,并且没有限制其必须是市,县或是其他级别

现要随时统计当前月份,各个省份和直辖市新注册的用户量,因为oracle中有start with等相关操作,这个功能可以得到较好的实现,但pgsql里,需要自己写递归查询,而且,输入并不是外部传入的一个变量或者定好的一个常量,而是另外一个表查询出的结果集(因为如果分开执行,查出所有user_info,再遍历地去调递归sql,性能损失极大),实现相当困难且不会有很好的性能。


最终解决方案:

更改表结构,city_info扩增一个字段city_root,用于存放一个city所属的省级city的id

写一个递归sql一次性更改数据库已有数据:

先查出所有省级city的id,遍历调用递归sql,

将当前省级city下的所有city(包含省级自身)的city_root填充为当前省级city的id:

<update id="changeOnce" parameterType="java.lang.Integer">
    update city_info t set t.city_root = #{Id}
    where t.id in
    (with RECURSIVE cte as
      (select t1.id, t1.pid from city_info t1 where t1.id = #{Id}
      union all
      select t2.id, t2.pid from conf_admin_city t2 inner join cte c on c.id = t2.pid
      ) select id from cte)
</update>

做完数据更改后,更改表的插入sql,使新插入的city记录,city_root字段填为父city的city_root


最后效果:性能非常好

因为现在进行统计的过程只需要连表查询就可以轻松搞定

<select id="getAddCount" resultMap="CountResult">
    select t1.city_root, count(1) as addCount
    from city_info t1, user_info t2
    where t2.register_city = t1.id
    and <![CDATA[t2.register_time < date_trunc( 'month', now())::timestamp + '1 month' ]]>
    and <![CDATA[t2.register_time >=  date_trunc( 'month', now())]]>
    group by t1.city_root
</select>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值