碰到一个需求,一个时间段内只允许有一个计划,也就是说数据库中的时间区间不能有重复或交叉,记录下从复杂到简单的简化过程。
1.刚开始想的时候感觉这个有很多种情况,然后把每一次情况都用sql标识出来,写的语句如下。
|
|
2.后来感觉太复杂了,就在论坛里发帖问了下,rails代码可以这么写
|
|
3.后来优化了一次,发现好多情况其实都是重复的,优化之后的情况为:
|
|
4.@quakewang 帮着理了一下思路,最后的结果为:
先是判断时间区段不重叠,有2种情况1234567 |start_a ----- end_a| |start_b ----- end_b| ---------------------------------------------|start_a ----- end_a| |start_b ----- end_b|
得出不重叠的表达式是:1start_a > end_b || end_a < start_b
那么不重叠就是取反1!(start_a > end_b || end_a < start_b)
布尔运算等价于1start_a <= end_b and end_a >= start_b
最终的结果为:1plan = Plan.where('start_time <= ? and end_time >= ?', end_at, start_at)