现有一个业务数据表栏目大概如下所示:id int 记录id
group_id int 分组id
income int 收入
expense int 开支
month_date date 月份时间,例如:2019-12-01
week int 第几周
我要实现的是获取某小组在任意时间范围之间的收入、开支及利润统计。
由于数据是按某月第几周的方式来新增的,而筛选的时间选择是年-月-日的方式,所以筛选时间的条件必须先由年-月-日格式转为某月几周的形式。这个转换过程本文就不讲述了。
我们就直接看,两个某月某周格式的时间范围,统计是如何实现的。
用的是laravel框架,本人一开始写的代码如下:$startMonth = '2019-11-01';
$startWeek= 2;
$endMonth = '2019-12-01';
$endWeek= 2;
$query = Finance::where(function($outQuery) use($startMonth, $startWeek, $endMonth, $endWeek){
$outQuery->orWhere(function($query) use($startMonth, $startWeek){
$query->where('month_date', $startMonth)
->where('week', '>=', $startWeek);
})
->orWhere(function($query) use($startMonth, $endMonth){
$query->where('month_date', '>', $startMonth)
->where('month_date', '
})
->orWhere(function($query) use($$endMonth, $endWeek){
$query->where('month_date', $endMonth)
->where('week', '<=', $endWeek);
});
});
上面代码逻辑有漏洞,你能看出来吗?
将上面代码转换成sql语句,如下:select * from zhai14_cost
where group_id = ?
and (
(date_time = ? and week >= ?)
or (date_time > ? and date_time < ?)
or (date_time=? and week <=?)
)
你还能看出来问题吗?
特殊情形是,当开始时间和结束都是同一个月同一周的时候,应该实现的功能就是查询那一个月那一周的数据。但是上面代码并不能达到这一目的。
为了方便分析,我们假定时间都是11月的第3周。
将数值代入到上面sql语句中去,得到如下:(date_time = '2019-11-01' and week >= 3)
or (date_time > '2019-11-01' and date_time < '2019-11-01')
or (date_time='2019-11-01' and week <=3)
中间一行是空区间,就可以忽略了。
剩下第一行和第三行所形成的范围就成了2019-11-01这整个月的时间了,而实际应该就只是2019年11月的第3周这一周的时间而已。
这就是上面代码的漏洞所在。
修补方法就是将开始时间和结束时间相等的情形考虑进去,最终代码如下所示:if( $startMonth == $endMonth ){
if( $startWeek == $endWeek ){
$query = Finance::where('month_date', $startMonth)
->where('week', $startWeek);
}else{
$query = Finance::where('month_date', $startMonth)
->where('week', '>=', $startWeek)
->where('week', '<=', $endWeek);
}
}else{
$query = Finance::where(function($outQuery) use($startMonth, $startWeek, $endMonth, $endWeek){
$outQuery->orWhere(function($query) use($startMonth, $startWeek){
$query->where('month_date', $startMonth)
->where('week', '>=', $startWeek);
})
->orWhere(function($query) use($startMonth, $endMonth){
$query->where('month_date', '>', $startMonth)
->where('month_date', '
})
->orWhere(function($query) use($$endMonth, $endWeek){
$query->where('month_date', $endMonth)
->where('week', '<=', $endWeek);
});
});
}
2019年12月07日 19:31文章创建
2019年12月07日 20:51文章发布