【问题标题】:Finding response time grouped by intervals查找按时间间隔分组的响应时间
【发布时间】:2020-08-09 13:20:51
【问题描述】:

我有一张桌子,上面有某些日志及其响应时间。我可以通过以下方式查询表以获取最近 1000 条记录的平均响应时间:

SELECT timestamp, count(*), avg(response_time) FROM table ORDER BY timestamp DESC LIMIT 1000

-- timestamp            count(*)      avg(response_time)
-- 2020-03-17 11:58:37  1000          0.27

但是,我希望在过去每千条记录中获得 N 条记录(以查看响应时间随时间的进展,以 1000 个请求为单位),即:

SELECT timestamp, count(*), avg(response_time) FROM table ORDER BY timestamp DESC LIMIT 1000
  UNION
SELECT timestamp, count(*), avg(response_time) FROM table ORDER BY timestamp DESC LIMIT 1000, 1000
  UNION ...

-- timestamp            count(*)      avg(response_time)
-- 2020-03-17 11:58:37  1000          0.27
-- 2020-03-17 11:38:09  1000          0.52
-- 2020-03-17 11:04:11  1000          1.04
-- and keep going, in groups of 1000 records...

是否有一种更简洁的方法来做到这一点,我可以按 1000 个块对事物进行分组?

【问题讨论】:

    标签: mysql sql date datetime group-by


    【解决方案1】:

    你似乎想要:

    SELECT count(*) no_records, avg(response_time) avg_response_time
    FROM table 
    WHERE timestamp >= now() - interval 1 day
    

    如果您希望按小时计算:

    SELECT 
        date_format(timestamp, '%Y-%m-%d %h:00:00') hr, 
        count(*) no_records, 
        avg(response_time) avg_response_time
    FROM table 
    WHERE timestamp >= now() - interval 1 day
    GROUP BY date_format(timestamp, '%Y-%m-%d %h:00:00)
    ORDER BY hr
    

    或者如果你想按 1000 条记录的块分组,那么(假设 MySQL 8.0),你可以使用row_number()

    SELECT 
        min(timestamp) first_timestamp,
        last(timestamp) first_timestamp,
        count(*) no_records, 
        avg(response_time) avg_response_time
    FROM table 
    WHERE timestamp >= now() - interval 1 day
    GROUP BY floor((row_number() over(order by timestamp) - 1) / 1000)
    ORDER BY first_timestamp
    

    【讨论】:

    • 不,我已经更新了问题。这只给了我一个结果——我想要每 1000 条记录的结果...
    • 感谢您的更新。但这将按小时分组(我也可以 GROUP BY hour(timestamp) 给定少于 24 小时的间隔。我将如何按每 1000 条记录分组?
    • 哈,这个新答案很棒!但是,唉,我在 MySQL 5.7 上:/
    【解决方案2】:

    你可以使用窗口函数做你想做的事。但是,唉,你不能在 MySQL 5.7 中。相反,使用变量:

    SELECT MIN(timestamp), MAX(timestamp), count(*), avg(response_time)
    FROM (SELECT t.*, (@rn := @rn + 1) as seqnum
          FROM (SELECT t.* FROM table  ORDER BY timestamp) t
               (SELECT @rn := 0) params
         ) t
    GROUP BY floor( (seqnum - 1) / 1000 )
    ORDER BY MIN(timestamp);
    

    【讨论】:

      猜你喜欢
      • 2011-12-20
      • 2017-10-27
      • 2011-02-08
      • 2019-06-28
      • 2018-10-12
      • 2016-09-21
      • 2017-09-06
      • 2021-03-06
      相关资源
      最近更新 更多