如何按时间段来进行数据统计并进行排序,请问该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 :joy:,请教下小伙伴们,该 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;
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 7

用 laravel 的模型关联,里面有个聚合关联模型。或者,你自己分三次查询了,先查用户,再分别根据用户 id 作为条件去查另两张表,最后,自己把数据处理一下,这样应该很快的,子查询这样写,如果表里数据很多,那妥妥慢的

1年前 评论
一个人的江湖 (楼主) 1年前

我觉得先把前15个用户查出来,然后再去关联查询应该会快很多

1年前 评论
一个人的江湖 (楼主) 1年前
随波逐流

可以使用 EXPLAIN来调优, 另外需要正确的加 索引

1年前 评论

我们之前的数据业务针对这类情况一般是采用自动作业脚本的方式,根据业务需要脚本可以每天执行一次或者半个小时执行一次,根据需求将统计的结果存入一个统计表中,这样数据量就大大降低了,然后页面展示主要展示这张表中的数据,提供一个实时按钮可供查询实时数据(慢)

1年前 评论
circle

可以用内存换时间, 根据用户 id 一次性查出 profitsbills 的记录再到内存中进行 sum,然后再进行数据拼接,拼成自己想要的结果

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!