选择总和达到700的记录

时间:2018-08-21 20:04:54

标签: mysql sql database

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

this is what the table looks like

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

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

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

这是否可能无需编写脚本就可以完成?

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

4 个答案:

答案 0 :(得分:1)

您在这里。如果数据是:

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  

答案 1 :(得分:0)

这将列出所有总分等于或超过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

答案 2 :(得分:0)

我假定您的版本是5.7或更低,即窗口功能不在窗口范围内(双关,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;

答案 3 :(得分:0)

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

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

时会出现匹配