zoukankan      html  css  js  c++  java
  • Sql 正确删除用户过期的数据

      怎样才算是正确的删除过期的数据呢?先交代一下前提,XX网站上面有一个放心企业专区,办理超级会员即可成为放心企业,放心企业可设置推荐职位展示在放心企业专区,信息都是存放在Info表中的,所谓的推荐职位就是把信息从Info表再写到推荐职位表(RecommPosition)中,而用户办理的超级会员是有有效期的,办理超级会员时会新写一条记录到会员办理记录表(PackageRecord)中,不会更改用户信息,采用关联用户表和会员办理记录表来实现,因为类似这样的东西还有很多,有些产品不合适就会被淘汰掉,如果每新出一个产品就在User表中新加字段来进行标识,那么久而久之User表中的字段就会很冗余,所以采用和对应的表进行关联来实现,这样可以避免后期维护的难度。额,回归正题,当用户办理的超级会员到期时,系统需要自动清理掉会员到期的用户设置的推荐职位信息,因为推荐职位表中的记录都是从Info表中写进来的,信息实际上都是存储在Info表中的,推荐职位表只是关联Info表的Id、专业、地区等部分信息用于筛选,所以推荐职位表相当于一张临时表,表中的记录可以进行物理删除。当然,如果你要拿来做数据分析的话也可以采用逻辑删除。

      删除会员到期的用户设置的推荐职位信息:

    delete [RecommPosition] where [UserId] in
    (
        select [UserId] from [PackageRecord] where [PackagePid]=1 and [EndTime]<GETDATE()
    )

      乍一看好像没有什么问题,但是我忽略了一个问题,因为会员办理记录表里记录的是各个会员的销售情况,会拿来做财务统计和数据分析,这种表的记录是不会被删除的,所以就可能会出现一个用户有多条记录的情况,所以我需要对用户Id进行去重。假如超级会员的有效期是一个月,有用户以前办理过超级会员,用了用觉得效果还不错这个月又想继续办理,这一个用户就有多条会员办理记录了,遇到这种情况我们上面的Sql语句就会误删除掉一部分用户的推荐职位。因为既有到期的会员办理记录又有未到期的会员办理记录的用户他事实上是属于放心企业的。所以我们只能删除掉超级会员过期且没有继续办理超级会员的用户设置的推荐职位信息。

      删除超级会员过期且没有继续办理超级会员的用户设置的推荐职位信息:

    --删除过期的用户且不在未过期的用户当中.
    delete [RecommPosition] where [UserId] in
    (
        select distinct [UserId] from [PackageRecord] where [PackagePid]=1 and [EndTime]<GETDATE()
    )
    and [UserId] not in
    (
        select distinct [UserId] from [PackageRecord] where [PackagePid]=1 and [EndTime]>=GETDATE()
    )

      这样删除是没有错了,但是上面的Sql用到了not in,效率不是很高,而且Sql语句不好理解,我们再想办法优化优化。

      删除用户的信息,但是只要他还有有效的会员办理记录则不能被删除,也就是说我们只能删除那些所有的到期时间中最大的到期时间都小于当前时间的用户的推荐职位信息

    delete [RecommPosition] where [UserId] in
    (
        select [UserId] from [PackageRecord] where [PackagePid]=1 group by [UserId] having MAX([EndTime])<GETDATE()
    )

      看到这里好像是没有什么问题了,但往往有你意想不到的事情发生,有一天博主发现,推荐职位表中竟然多了一条非超级会员的推荐信息,真不知道这条数据是怎么写进来的,而且这个时候你可能会发现我目前这个sql根本就删不掉这条非超级会员的推荐信息,为啥呢?因为我只删除了办理过超级会员且超级会员已经过期的用户,对于那些有推荐信息但是压根就没买过超级会员或者会员购买记录被删除的用户根本无法实施删除,压根就没有考虑过竟然会有非超级会员的推荐信息,得了,赶紧完善sql去。

    delete [RecommPosition] where [UserId] in
    (
        select [UserId] from [PackageRecord] where [PackagePid]=1 group by [UserId] having MAX([EndTime])<GETDATE()
    )
    or [UserId] not in 
    (
        select distinct UserId from [PackageRecord] where [PackagePid]=1
    )

      正确的理解应该是,不是超级会员的推荐信息就要清理,不单单是清理过期的超级会员的信息,还包括那些压根就没办理过超级会员或者会员购买记录被删除的用户信息

      好了,写到这里这篇博客也差不多了,感觉写的有点过于啰嗦,慢慢改进吧!

      总结:1、不要把问题想得过于简单,尽量考虑全面一点!

         2、有时候多想一步,就能收获很多,慢慢的也就进步了,加油,晓菜鸟 

  • 相关阅读:
    一根网线实现双机互联共享文件
    预编译指令与宏定义
    程序的编译链接过程
    windows消息机制(MFC)
    【SpringBoot】SpringBoot Servlet容器(十一)
    【SpringBoot】SpringBoot Servlet三大组件 Servlet、Filter、Listener(十)
    【SpringBoot】SpringBoot 错误处理机制(九)
    【SpringBoot】SpringBoot 国际化(七)
    【SpringBoot】SpringBoot与Thymeleaf模版(六)
    【SpringBoot】SpringBoot与SpringMVC自动配置及静态资源(五)
  • 原文地址:https://www.cnblogs.com/52XF/p/4172382.html
Copyright © 2011-2022 走看看