繁体   English   中英

选择总和达到700的记录

[英]Select record where SUM reaches 700

我有一个分数表,其中的每条记录都带有可变数量的分数,时间戳和移动用户ID。

这是桌子的样子

我的任务是弄清楚用户获得700点的平均时间。

我如何使用SQL找出total_points的SUM达到700的记录ID,以便比较时间戳并针对每个用户执行此操作。

python脚本是解决此问题的最佳方法吗? 假设我为数据库中的用户获得了2个时间戳(有史以来第一个时间戳,total_points达到700个时间戳),这些用户的得分> = 700,以便得出我所有用户的平均时间。

还是无需编写脚本就可以做到这一点?

任何帮助或指导表示赞赏。

干得好。 如果数据是:

create table score (
  id int,
  mobile_user_id int,
  report_date datetime,
  total_points int
);

insert into score (id, mobile_user_id, report_date, total_points)
  values
  (1, 123, '2018-07-23', 100),
  (1, 123, '2018-07-24', 200),
  (1, 123, '2018-07-25', 500),
  (1, 123, '2018-07-26', 200),
  (2, 124, '2018-06-03', 800),
  (3, 125, '2018-06-17', 150);

查询是:

with a as (
  select
      id, mobile_user_id, report_date,
      sum(total_points) over(partition by id order by report_date)
        as points_so_far
    from score
), 
b as (
  select id, min(report_date) as obtain_date
    from a where points_so_far >= 700
    group by id
)
select s.id, s.initial_date, b.obtain_date
  from b join (
    select id, min(report_date) as initial_date 
      from score group by id  
  ) s on s.id = b.id;

结果:

id           initial_date         obtain_date          
-----------  -------------------  ---------------------
1            2018-07-22 20:00:00  2018-07-24 20:00:00  
2            2018-06-02 20:00:00  2018-06-02 20:00:00  

这将列出所有总得分等于或超过700分的用户。 它还列出了用户的开始日期和结束日期,以及该时间段的总天数。

SELECT
    `mobile_user_id`,
    MIN(`report_date`) as `points_start`,
    MAX(`report_date`) as `points_end`,
    DATEDIFF(MIN(`report_date`),MIN(`report_date`)) as `duration_days`
    count(`total_points`) as `total`
FROM `points_table`
GROUP BY `mobile_user_id`
HAVING `total` >= 700

我假设您的版本是5.7或更低,即窗口函数不在窗口范围内(pun,ha,ha)。 因此,您需要使用子查询来计算滚动总和,该子查询求和来自较早报告的所有点。

使用该过滤器仅过滤点总数达到700或之后的报告。

当用户达到或超过700分时,按用户对结果进行分组并获得每个用户的最小时间戳。

内部加入每个用户的整体最小时间戳,您可以通过分组再次获得。 内部联接还将消除第二个分组子查询中来自少于700点的用户的行。

获取两个时间戳的差,然后计算该差的平均值。

SELECT avg(timestampdiff(SECOND, x2.report_date, x1.report_date)) duration
       FROM (SELECT t1.mobile_user_id,
                    min(t1.report_date) report_date
                    FROM elbat t1
                    WHERE (SELECT sum(t2.total_points)
                                  FROM elbat t2
                                  WHERE t2.mobile_user_id = t1.mobile_user_id
                                        AND (t2.report_date < t1.report_date
                                              OR t2.report_date = t1.report_date
                                                 AND t2.id < t1.id)) >= 700
                    GROUP BY t1.mobile_user_id) x1
            INNER JOIN (SELECT t1.mobile_user_id,
                               min(t1.report_date) report_date
                               FROM elbat t1
                               GROUP BY t1.mobile_user_id) x2
                                        ON x2.mobile_user_id = x1.mobile_user_id;

您需要的是具有这种模式的表-

user_id, time_when_700_points_achieved (timestamp) , user_start_time (timestamp)

这是它的查询-

select user_id, max(report_date) as time_when_700_points_achieved , min(report_date) as user_start_time  
from tablename
where points <= 700
group by user

完成此操作后,您可以轻松获取两个时间戳之间的minute差。

假设-当用户达到700岁时将出现点击

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM