- 需求 根据 姓名 和 年份 获取 该 account 的 该年所有月份的 报表数据 (月份,排名,费用,全年费用)
1. 用传过来得到年份查询该年份12个月数据
第一反应 一个月一个月查嘛 虽然只传了一个年份 数据库里 时间 字段的数据类型是 date
所以存在表里的 时间是 yyyy-mm-dd 格式的 只查询 某年月的 肯定就要模糊查询 该年月的数据然后统计下
我的方法
// 首先 得到前端传的 姓名 和 年份
$name = input('name');
$year = input('year', date("Y"));
// 根据 年月模糊查询 肯定要个准确滴嘛 yyyy-mm 格式
for ($i = 1; $i <= 12; $i++) {
一开始是直接遍历的时候 拼接 后面发现 模糊查询年月 2021-1 要写成 2021-01 所以.....
// 加了个这个if 判断 看起来很蠢但是一时又没想到其他方法
if ($i < 10) {
$date = $year . '-0' . $i;
} else {
$date = $year . '-' . $i;
}
// 先查个 全年总费用出来
$total_year_fee = Db::table('tm_order_report_date')->alias('ord')
->join("tm_account a ", "ord.account_id=a.id and a.name = '{$name}'")
->leftJoin("system_user u", "u.id=a.admin_id")
->field("a.name as name,a.id as account_id,u.nick as team_name,sum(ord.order_num) as order_num,sum(ord.bi_ci_fee) as total_bi_ci_fee")
->group('name')
->whereTime('order_date', 'year')->select();
// 这个 whereTime('order_date', 'year') 是默认查本年的
if (!empty($total_year_fee)) {
$this_month_details['total_bi_ci_fee'] = $total_year_fee[0]['total_bi_ci_fee'];
}
// 查出该人该月的详细信息
$this_month_details['data'][$i] = Db::table('tm_order_report_date')->alias('ord')
->join("tm_account a ", "ord.account_id=a.id and a.name = '{$name}'")
->leftJoin("system_user u", "u.id=a.admin_id")
->field("a.name as name,u.nick as team_name,sum(ord.order_num) as order_num,sum(ord.bi_ci_fee) as total_bi_ci_fee")
->group('name')->where('ord.order_date', 'like', '%' . $date . '%')->select();
// 查出该人该月的 排名
$this_month_rank = Db::table('tm_order_report_date')->alias('ord')
->join("tm_account a ", "ord.account_id=a.id and a.admin_id > 0 and {$this->exadmin}")
->field("a.name as name,sum(ord.order_num) as order_num,sum(ord.bi_ci_fee) as total_bi_ci_fee")
->group('name')->where('ord.order_date', 'like', '%' . $date . '%')->order(['total_bi_ci_fee' => 'desc'])->select();
// 遍历一下把 排名插到 详细信息里面
foreach ($this_month_rank as $key => &$value) {
$value['no'] = ($key + 1);
if ($value['name'] == $name) {
$this_month_details['data'][$i]['rank'] = $value['no'];
}
}
// 再遍历一下 将 没查出来的月份的数据 给0 不然会不显示(特殊需求) ?!!
foreach ($this_month_details['data'] as $key => &$tmd) {
if (empty($tmd)) {
$tmd[0]['order_num'] = 0;
$tmd[0]['total_bi_ci_fee'] = 0;
$this_month_details['data'][$i]['rank'] = 0;
}
}
}
// for 循环完了吧 返回输出给前端...... 看一眼就知道这效率....杠杠的....烂...
// 无能本人只能为实现效果写出垃圾代码 折磨 数据库 , 网络 ,还有前端......
return json(['data' => $this_month_details]);
无奈返回给前端的json太恶心和变态… 虽然还是
修改后的方法!!!!!!!!!!!!
$name = _input_('name', 'empty', '业务员姓名必传');
$year = input('year', date("Y"));
$total_year_fee = Db::table('tm_order_report_date')->alias("d")
->join("tm_account a ", "a.id=d.account_id")
->where(['a.name' => $name])
->where("d.order_date", "like", $year . "%")
->sum("d.bi_ci_fee");
$total_year_fee = round($total_year_fee / 10000, 2); //单位万元
这部分内容 与 之前的步骤大致 都是取出总费用 接下来........!!!
$data = Db::table("tm_order_report_date")->alias("d")
->join("tm_account a ", "a.id=d.account_id")
->leftJoin("system_user u", "u.id=a.admin_id")
->where(['a.name' => $name])
->where("d.order_date", "like", $year . "%")
->field("a.name,u.email as team,sum(d.bi_ci_fee) as bi_ci_fee,sum(d.order_num) as order_num,left(d.order_date,7) as month")
->group("DATE_FORMAT(d.order_date,'%Y-%m')")
->order("month asc")
->select();
模糊查询是有的 但是有个特殊的地方 left(d.order_date,7) as month
mysql的left函数 放入两个参数 一个是 时间字段 一个是 7
再加上 ->group("DATE_FORMAT(d.order_date,'%Y-%m')")
直接分组查询出 yyyy-mm-dd 字段前7位一样 不就刚好是某年某月的数据吗
并且 ->order("month asc") 根据年份 排序 直接 1-12月乖溜站好.
// 最后来个遍历 把数据拍好 并加上个月份
$ret_data = [];
for ($i = 1; $i <= 12; $i++) {
foreach ($data as $k => $v) {
$month = substr($v['month'], 5, 2);
if (intval($month) == $i) {
$v['bi_ci_fee'] = round($v['bi_ci_fee'] / 10000, 2);
$ret_data[$i] = ['month' => $i, 'name' => $v['name'], 'team' => $v['team'], 'bi_ci_fee' => $v['bi_ci_fee'], 'order_num' => $v['order_num']];
}
}
if (!isset($ret_data[$i])) {
$ret_data[$i] = ['month' => $i, 'name' => $v['name'], 'team' => $v['team'], 'bi_ci_fee' => 0, 'order_num' => 0];
}
}
$ret_data = array_values($ret_data);
// 返回数据 一气呵成 还有 排名去掉了 排名过于麻烦 又不需要了....
return json(['total_year_fee' => $total_year_fee, 'data' => $ret_data]);
果然 这样前端可以少掉些头发了 而且效率杠杠的
总结1下.
MySQL left()函数的使用
https://blog.csdn.net/weixin_30412847/article/details/113213382
https://blog.csdn.net/moakun/article/details/82086078
https://blog.csdn.net/weixin_30745553/article/details/101970198
- 根据传过来的 姓名 和 月份 查出该月每天的数据 (日期,排名,费用,全年费用)
2. 根据传过来的姓名和月份查出该月每天的数据
同样的 第一反应 传一个月份 得到年月 再得到该月的总天数 做遍历的次数 每次遍历拼接一下 年-月-日(第几次)作为查询的条件 上code
老样子 先接收一下参数 name 和 month
$name = _input_('name', 'empty', '业务员姓名必传');
$year = input('year', date("Y"));
$month = _input_('month', 'empty', '月份参数没有传');
又要判断一下传的月份拼接成 yyyy-mm-dd
if ($month < 10) {
$date = $year . '-0' . $month;
} else {
$date = $year . '-' . $month;
}
一个特殊必要的方法 获取该年月到底有多少天
function get_day($date)
{
$tem = explode('-', $date); //切割日期 得到年份和月份
$year = $tem['0'];
$month = $tem['1'];
if (in_array($month, array('1', '3', '5', '7', '8', '01', '03', '05', '07', '08', '10', '12'))) {
// $text = $year.'年的'.$month.'月有31天';
$text = '31';
} elseif ($month == 2) {
if ($year % 400 == 0 || ($year % 4 == 0 && $year % 100 !== 0)) //判断是否是闰年
{
// $text = $year.'年的'.$month.'月有29天';
$text = '29';
} else {
// $text = $year.'年的'.$month.'月有28天';
$text = '28';
}
} else {
// $text = $year.'年的'.$month.'月有30天';
$text = '30';
}
return $text;
}
得到的该月天数 就是遍历的次数 上遍历
for ($i = 1; $i <= $this->get_day($date); $i++) {
if ($i < 10) {
$ymd = $date . '-0' . $i;
} else {
$ymd = $date . '-' . $i;
}
// 今日数据排行
$day_details[$i] = Db::table('tm_order_report_date')->alias('ord')
->join("tm_account a ", "ord.account_id=a.id and a.name = '{$name}'")
->leftJoin("system_user u", "u.id=a.admin_id")
->field("a.name as name,sum(ord.order_num) as order_num,sum(ord.bi_ci_fee) as total_bi_ci_fee")
->group('name')->where('ord.order_date', 'like', '%' . $ymd . '%')->select();
// 今日数据排行
$day_range = Db::table('tm_order_report_date')->alias('ord')
->join("tm_account a ", "ord.account_id=a.id and a.admin_id > 0 and {$this->exadmin}")
->field("a.name as name,sum(ord.order_num) as order_num,sum(ord.bi_ci_fee) as total_bi_ci_fee")
->group('name')->where('ord.order_date', 'like', '%' . $ymd . '%')->order(['total_bi_ci_fee' => 'desc'])->select();
// 为了得到当日排名 查出当时排行名称相同的排名即排序
foreach ($day_range as $key => &$value) {
$value['no'] = ($key + 1);
if (strcmp($value['name'], $name) == 0) {
$day_details[$i][0]['date'] = substr($ymd, 5);
$day_details[$i][0]['rank'] = $value['no'];
}
}
// 再把没查到的是空的 字段都给个0显示下
foreach ($day_details as $key => &$dd) {
if (empty($dd)) {
$day_details[$key][0]['order_num'] = 0;
$day_details[$key][0]['rank'] = 0;
$day_details[$key][0]['total_bi_ci_fee'] = 0;
$day_details[$i][0]['date'] = substr($ymd, 5);
}
}
}
OK了 输出数据 -_-||-_-||-_-|| huangdeyipi
return json(['data' => $day_details]);
数据出是出来了 效率低 而且 前端也难处理… OMG
改tmd 改 改 改 思路: 可以先查出一直年月的数据 根据 年月日字段排序 和 统计总费用 再遍历插入数组666
$name = _input_('name', 'empty', '姓名必传');
$year = input('year', date("Y"));
$month = _input_('month', 'empty', '月份参数没有传');
sprintf() 方法 %02s 2s 将month写成前面0填充的两位字符串
$month = $year . '-' . sprintf("%02s", $month);
直接联表查询 根据年月 根据日期大小排序 查询出该月的所有数据 并统计总费用
$data = Db::table("tm_order_report_date")->alias("d")
->join("tm_account a ", "a.id=d.account_id")
->where(['a.name' => $name])
->where("order_date", "like", $month . "%")
->field("sum(bi_ci_fee) as bi_ci_fee,sum(order_num) as order_num,order_date")
->group("order_date")
->order("order_date asc")
->select();
老方法 获取 该年月总天数
$days = $this->get_day($month);
$ret_data = [];
遍历插入 数据 substr($v['order_date'], 8, 2); 把年月日 从第八位开始截取 2 位
例如 2021-03-03 截取后就是 03 俺需要 从5截5 是 03-03 区分日期
for ($i = 1; $i <= $days; $i++) {
foreach ($data as $k => $v) {
$day = substr($v['order_date'], 8, 2);
// 如果遍历的日期数 和 次数相等 那就ok了 是当天的数据
if (intval($day) == $i) {
//$v['bi_ci_fee'] = round($v['bi_ci_fee'] / 10000, 2);
$ret_data[$i] = ['day' => substr($v['order_date'], 5, 5), 'bi_ci_fee' => $v['bi_ci_fee'], 'order_num' => $v['order_num']];
}
}
// 不存在就给0
if (!isset($ret_data[$i])) {
$ret_data[$i] = ['day' => substr($v['order_date'], 5, 5), 'bi_ci_fee' => 0, 'order_num' => 0];
}
}
返回数组中所有的值(不保留键名):
$ret_data = array_values($ret_data);
return json(['data' => $ret_data]);
大哥 搞腚 舒服了