主表是用户user_member表,关联的表有登录表mobile_login_log(明细)、产品统计表product_statistics(日期汇总型)、订单表order_table(明细)、转换记录表trans_log(明细)。涉及不同类型表,所以采用直接左连接查询会出现一些count/sum字段重复统计的情况,最后的查询数据结构为用户列表,字段为每个用户对应的分字段汇总数据,如用户10001登录次数、转文字次数、充值金额等。
public function getWordStatisticsList($request)
{
$keyword = $request->input('keyword', '');
$order_situation = $request->input('order_situation', '');
$limit = $request['limit'];
$page = $request['page'] - 1;
$order_by_column = $request->input('field', 'user_id');
$order_by_option = $request->input('order', 'desc');
$between = $this->getBetween($request);
$where['user_member.appid'] = 3;
if (isset($order_situation) && $order_situation != '') {
$where['user_member.order_situation'] = $order_situation - 1;
}
$count = UserMember
::where($where)
->when($keyword, function ($query) use ($keyword) {
$query->where('user_member.id', 'like', "%$keyword%");
})
->count();
$product_statistics_sql = '(
SELECT COALESCE(sum( recording_time ),0) AS recording_time,
COALESCE(sum( video_to_audio_time ),0) AS video_to_audio_time,
COALESCE(sum( audio_clips ),0) AS audio_clips,
date_time,
user_id
FROM product_statistics';
$mobile_login_sql = '(
SELECT count( id ) AS login_time,
user_id,status,
create_time FROM mobile_login_log where status = 1';
$order_table_sql = '(
SELECT COALESCE ( sum( amount ), 0 ) AS amount,
user_id,
pay_status,
pay_time from order_table where pay_status = 1 and appid = 3';
$trans_log_sql = '(
SELECT COALESCE ( sum( if(providers=1,use_time,0) ), 0 ) AS baidu_use_time,
COALESCE ( sum( if(providers=2,use_time,0) ), 0 ) AS ali_1_use_time,
COALESCE ( sum( if(providers=3,use_time,0) ), 0 ) AS ali_2_use_time,
count( id ) as trans_time ,
user_id,
date from trans_log where status = 1';
if ($between) {
$product_statistics_sql .= ' where date_time between ' . $between[0] . ' and ' . $between[1];
$mobile_login_sql .= ' and create_time between ' . $between[0] . ' and ' . $between[1];
$order_table_sql .= ' and pay_time between ' . $between[0] . ' and ' . $between[1];
$trans_log_sql .= ' and date between ' . $between[0] . ' and ' . $between[1];
}
//列表数据
$list_query = UserMember::select(DB::raw('
user_member.id as user_id,
user_member.order_situation,
COALESCE(sum(bb.recording_time),0) AS recording_time,
COALESCE(sum( bb.video_to_audio_time),0) AS video_to_audio_time,
COALESCE(sum( bb.audio_clips ),0) AS audio_clips,
COALESCE(sum( ee.trans_time ),0) AS trans_time,
COALESCE(sum( ee.baidu_use_time ),0)/3600 + COALESCE(sum( ee.ali_1_use_time ),0)/3600 AS use_time,
COALESCE(sum( ee.baidu_use_time ),0)/3600 * 1.2 + COALESCE(sum( ee.ali_1_use_time ),0)/3600 * 1.56 AS trans_price,
COALESCE(sum( cc.login_time ),0) AS login_time,
COALESCE(sum( cc.login_time ),0)* 0.03 AS login_price,
COALESCE(sum( ee.baidu_use_time ),0)/3600 * 1.2 + COALESCE(sum( ee.ali_1_use_time ),0)/3600 * 1.56 + COALESCE(sum( cc.login_time ),0)* 0.03 as total_price,
COALESCE(sum(dd.amount),0) AS amount,
COALESCE(sum(dd.amount),0) - (COALESCE(sum( ee.baidu_use_time ),0)/3600 * 1.2 + COALESCE(sum( ee.ali_1_use_time ),0)/3600 * 1.56 + COALESCE(sum( cc.login_time ),0)* 0.03) AS profits
'))
->LeftJoin(DB::raw($product_statistics_sql . ' GROUP BY user_id ) bb'), function ($join) {
$join->on('user_member.id', '=', 'bb.user_id');
})
->leftJoin(DB::raw($mobile_login_sql . ' GROUP BY user_id) cc'), function ($join) {
$join->on('user_member.id', '=', 'cc.user_id');
})->LeftJoin(DB::raw($order_table_sql . ' group by user_id) dd'), function ($join) {
$join->on('user_member.id', '=', 'dd.user_id');
})
->leftJoin(DB::raw($trans_log_sql . ' group by user_id) ee'), function ($join) {
$join->on('user_member.id', '=', 'ee.user_id');
})
->where($where)
->when($keyword, function ($query) use ($keyword) {
$query->where('user_member.id', 'like', "%$keyword%");
});
if (empty($keyword)) {
$list_query->groupBy('user_member.id');
}
if ($order_by_column && $order_by_option) {
$list_query->orderBy($order_by_column, $order_by_option);
}
$list = $list_query->offset($page * $limit)->limit($limit)->get();
if (!$count) {
$list = [];
}
return [
'count' => $count,
'data' => $list,
'msg' => '',
'code' => 0,
];
}