怎样才算是正确的删除过期的数据呢?先交代一下前提,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、有时候多想一步,就能收获很多,慢慢的也就进步了,加油,晓菜鸟

Sql 正确删除用户过期的数据的更多相关文章

  1. SQL批量删除用户表(先删除所有外键约束,再删除所有表)

    --批量删除用户表 --1.删除外键约束DECLARE c1 cursor for     select 'alter table ['+ object_name(parent_obj) + '] d ...

  2. oracle 删除用户及相关表数据,释放磁盘空间

    来源于:http://www.itpub.net/thread-513609-1-1.html http://bbs.csdn.net/topics/330251089 http://blog.csd ...

  3. SQL Server删除用户失败的解决方法

    在删除SQL Server用户时,有时会报错:Microsoft SQL Server错误: 15138删除对于用户失败,数据库主体在该数据库中拥有架构,无法删除.删除 对于 用户“*****”失败. ...

  4. 一条sql关联删除多张表数据

    现有6张表存在关联关系,要删除主表则其他5张表关联数据也要一块删掉(单条sql多id批量删除) delete t1,t2,t3,t4,t5,t6 FROM rmd_v AS t1 LEFT JOIN ...

  5. SQL 遍历删除所有表的数据

    https://www.cnblogs.com/yige/p/5193253.html declare @sqlTabName varchar(100);-- 声明游标DECLARE C_Employ ...

  6. linux下如何完全删除用户

    1.首先进入系统创建一个用户 [root@localhost /]# useradd haha   #创建用户  haha是用户名 [root@localhost /]# passwd haha    ...

  7. SQL SERVER 2008 R2 自动备份并删除过期备份数据

        我们的系统维护的过程中肯定需要对数据库进行定期的备份,但是如果定时手工备份的话,不但浪费时间,也不能保证每次都可以按时备份,所以自动备份成为了我们的不二选择,但是定时备份需要定期清理备份文件, ...

  8. Oracle创建删除用户,角色,表空间,导入导出数据库命令总结(转载)

    无意间看到一篇文章,觉得对于ORACLE的新手很实用,特转载,原文出处这里 说明:在创建数据库时输入的密码,是修改系统默认的密码,以system和sysman等系统默认身份登录时要输入的密码就是修改后 ...

  9. SQL server 语句新建用户、对用户授权、删除用户实例

    Grant select on tb to db_user --给db_user用户授权 tb表 查询权限 一.命令操作 USE mydb GO --1. 新建测试用户 --1.1 添加登录用户和密码 ...

随机推荐

  1. poj2386(简单的dfs/bfs)

    题目链接:http://poj.org/problem?id=2386 Description Due to recent rains, water has pooled in various pla ...

  2. Raspbian首次安装后无法使用SSH链接

    使用Putty连接树莓派,出现Network Error:Connection Refused 新版的Raspbian系统默认禁用了SSH. 解决方法:在/boot分区创建名为"ssh&qu ...

  3. bzoj2989&&4170数列——二进制分组+主席树

    题意的转化挺巧妙的 可以联想到曼哈顿距离! 并且,所谓的修改还要查询历史版本,并且修改之间不动只算一次,不就是给平面上加一个点吗? 看成(x,a[x])的点 就是一个菱形区域 转切比雪夫距离,变成矩形 ...

  4. MATLAB:图像裁切(imcrop函数)

    对图像进行裁切可用imcrop函数,实现过程如下: close all; %关闭当前所有图形窗口,清空工作空间变量,清除工作空间所有变量 clear all; clc; [A,map]=imread( ...

  5. tcp的4次挥手、三次握手

    1. TCP短连接模拟一种TCP短连接的情况:1. client 向 server 发起连接请求2. server 接到请求,双⽅建⽴连接3. client 向 server 发送消息4. serve ...

  6. mysql盲注学习-1

    mysql: 1.left() //left()函数 left(a,b)从左侧截取a,的b位 2.mid() //mid()函数 参数 描述 column_name 必需.要提取字符的字段. star ...

  7. python自动化运维之路~DAY8

    python自动化运维之路~DAY8 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.线程进程介绍 为了方便我们队线程和进程的理解,我们来画2组图,方便我们对python中的线程 ...

  8. Swift真机调试时报错dyld: Library not loaded: @rpath/libswiftCore.dylib

    dyld: Library not loaded: @rpath/libswiftCore.dylib Referenced from: /private/var/mobile/Containers/ ...

  9. ThinkPHP 3.2 路径问题

    一.阿帕奇域名已经开始访问的时候:(去掉index.php) 访问路径: http://wechatu.xd107.com/Pay/Index/payTo JS路径代码: var $URL = &qu ...

  10. outlook关闭时最小化工具

    outlook本身不能支持设置点击关闭按钮时最小化,而是直接退出.需要借助一个加载项实现: Keep Outlook Running. Keep Outlook Running主页:https://s ...