如何按时间段来进行数据统计并进行排序,请问该SQL该如何实现
需要解决的问题:
以用户表 users
为主表,关联查询(或者其他方案)该用户的 待入账收益
,待入账单数
,已入账收益
,已入账单数
,并支持通过 时间段
来进行筛选统计,且支持 按收益金额
或 单数
排序,有分页,要导出
表结构(简版)
用户表
users
:数据量,百万id name mobile 33 张三 13333333333 44 李四 14444444444 待入账表
profits
:数据量几万id user_id amount created_at 1 33 1.32 2022-08-20 17:07:50 2 33 0.85 2022-08-21 17:07:50 3 44 0.95 2022-08-22 17:07:50 4 44 0.15 2022-08-23 17:07:50 账单表
bills
:数据量,千万id user_id bill_no amount created_at 1 33 B111111 1.32 2022-08-23 17:07:50 2 33 B222222 0.85 2022-08-22 17:07:50 3 44 B333333 0.95 2022-08-20 17:07:50 4 44 B444444 0.15 2022-08-21 17:07:50
数据示例:20-21号的统计数据,按 profit_amount 倒序排列,结果如下
id | user_id | mobile | profit_amount | profit_num | bill_amount | bill_num |
---|---|---|---|---|---|---|
1 | 33 | 13333333333 | 2.17 | 2 | 0 | 0 |
2 | 44 | 14444444444 | 0 | 0 | 1.1 | 2 |
自己写的 sql太烂了,执行时间 45s
,请教下小伙伴们,该 sql 该如何写,或者其他的解决方案也行
SELECT
`users`.`id`,
`users`.`name`,
`users`.`mobile`,
`users`.`created_at`,
IFNULL(profit_amount, 0) AS profit_amount,
IFNULL(bill_amount, 0) AS bill_amount
FROM `users`
LEFT JOIN (
SELECT `user_id`, SUM(amount) AS profit_amount, COUNT(id) AS profit_num
FROM `profits` GROUP BY `user_id`
) `p` ON `p`.`user_id` = `users`.`id`
LEFT JOIN (
SELECT `user_id`, SUM(amount) AS bill_amount, COUNT(id) AS bill_num
FROM `bills` GROUP BY `user_id`
) `b` ON `b`.`user_id` = `users`.`id`
LIMIT 0, 15;
用 laravel 的模型关联,里面有个聚合关联模型。或者,你自己分三次查询了,先查用户,再分别根据用户 id 作为条件去查另两张表,最后,自己把数据处理一下,这样应该很快的,子查询这样写,如果表里数据很多,那妥妥慢的
我觉得先把前15个用户查出来,然后再去关联查询应该会快很多
可以使用
EXPLAIN
来调优, 另外需要正确的加索引
我们之前的数据业务针对这类情况一般是采用自动作业脚本的方式,根据业务需要脚本可以每天执行一次或者半个小时执行一次,根据需求将统计的结果存入一个统计表中,这样数据量就大大降低了,然后页面展示主要展示这张表中的数据,提供一个实时按钮可供查询实时数据(慢)
可以用内存换时间, 根据用户 id 一次性查出
profits
和bills
的记录再到内存中进行 sum,然后再进行数据拼接,拼成自己想要的结果