【问题标题】:MySQL Moving daterange with set intervalMySQL以设定的间隔移动日期范围
【发布时间】:2019-11-26 12:45:41
【问题描述】:

这是我目前所拥有的

SELECT messageDatestamp 
     , count(messageDatestamp)  
  From table 
 where messageDatestamp between '2019-01-01 07:25:42' AND date_add('2019-01-01 07:25:45' , INTERVAL 1 SECOND)  
 group 
    by UNIX_TIMESTAMP(messageDatestamp)  
 ORDER 
    BY messageDatestamp asc;

messageDatestamp 列数据

2019-01-01 07:25:43
2019-01-01 07:25:43
2019-01-01 07:25:43
2019-01-01 07:25:43
2019-01-01 07:25:43
2019-01-01 07:25:43
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:45
2019-01-01 07:25:45
2019-01-01 07:25:45
2019-01-01 07:25:45
2019-01-01 07:25:45

输出

2019-01-01 07:25:43, 6
2019-01-01 07:25:44, 11
2019-01-01 07:25:45, 12

我不想为每个日期范围执行一个 select 语句,其中结束日期每隔一秒递增一次,如下例所示。

在“2019-01-01 07:25:42”和“2019-01-01 07:26:43”之间

在“2019-01-01 07:25:42”和“2019-01-01 07:26:44”之间

在“2019-01-01 07:25:42”和“2019-01-01 07:26:45”之间

有没有办法使用一个查询来增加结束日期或添加上一个计数值?

这就是我希望 MySQL 输出的内容。

2019-01-01 07:25:43, 6  (Count is between  07:25:42 and  07:25:43)
2019-01-01 07:25:44, 17 (Count is between  07:25:42 and  07:25:44)
2019-01-01 07:25:45, 22 (Count is between  07:25:42 and  07:25:45)

【问题讨论】:

  • 22如何计算?我会理解 23 或 29,但不是 22。
  • messageDatestamp 是什么类型的?只是询问,因为名称中带有标记的字段通常是 ​​VARCHAR。
  • 他们的类型是日期时间
  • 07:25:42 和 07:25:45 之间的总行数为 22

标签: mysql sql


【解决方案1】:

有没有办法使用一个查询来增加结束日期或添加上一个计数值?

你可以使用lag():

SELECT MIN(messageDatestamp), COUNT(*),
       (COUNT(*) + LAG(COUNT(*), 1, 0) OVER (ORDER BY MIN(messageDatestamp))
       ) as cnt_2
FROM table 
WHERE messageDatestamp BETWEEN '2019-01-01 07:25:42' AND date_add('2019-01-01 07:25:45' , INTERVAL 1 SECOND)  
GROUP BY UNIX_TIMESTAMP(messageDatestamp) 
ORDER BY messageDatestamp asc;

编辑:

我明白了,我误解了你的问题。您只需要一个累积计数:

你可以使用lag():

SELECT MIN(messageDatestamp), COUNT(*),
       SUM(COUNT(*))OVER (ORDER BY MIN(messageDatestamp)) as cnt_2
FROM table 
WHERE messageDatestamp BETWEEN '2019-01-01 07:25:42' AND date_add('2019-01-01 07:25:45' , INTERVAL 1 SECOND)  
GROUP BY UNIX_TIMESTAMP(messageDatestamp) 
ORDER BY messageDatestamp asc;

【讨论】:

  • 这个问题是它需要在计算当前值之前添加所有以前的计数值,否则它所做的只是移动两个。它不会按预期工作超过前两个计数。对于 07:25:45,它应该是 cnt_2 + count(*) 这将 = 17 + 5 = 22
  • @LiamHendricks 。 . .我不明白你的例子。您说您想将当前行中的值添加到前一个计数中,而不是前一个 cumulative 计数。您只需要一个累积总和。
  • 谢谢,这正是我需要的结果;对不起,我试图为我正在尝试做的事情想出正确的术语时造成的混乱。
【解决方案2】:

在 MySql 8.0 中,可以对一个正常的 COUNT 求和。
使用 SUM OVER 的 ORDER BY 将计算累计总数。

如果 messageDatestamp 是 TIMESTAMP(6),那么比较它可能会被截断为秒。

SELECT DATE_FORMAT(messageDatestamp,'%Y-%m-%d %H:%i:%s') AS messageDatestamp
,SUM(COUNT(*)) OVER (ORDER BY DATE_FORMAT(messageDatestamp,'%Y-%m-%d %H:%i:%s')) AS CumulativeCount
FROM `table` t
WHERE messageDatestamp >= TIMESTAMP('2019-01-01 07:25:42')
  AND messageDatestamp < TIMESTAMP('2019-01-01 07:25:45','00:00:01')
GROUP BY DATE_FORMAT(messageDatestamp,'%Y-%m-%d %H:%i:%s')
ORDER BY messageDatestamp ASC;

在此处使用 DATE_FORMAT 将时间戳截断为秒。
因为UNIX_TIMESTAMP 可能会在 2038 年引起问题。

更新

如果messageDatestampDATETIME(0),则不需要将其截断为秒。
然后可以对 SQL 进行高尔夫编码。

SELECT messageDatestamp
,SUM(COUNT(*)) OVER (ORDER BY messageDatestamp) AS CumulativeCount
FROM `table` t
WHERE messageDatestamp >= '2019-01-01 07:25:42'
  AND messageDatestamp <= '2019-01-01 07:25:45'
GROUP BY messageDatestamp
ORDER BY messageDatestamp ASC;

dbfiddle here

的测试

【讨论】:

    猜你喜欢
    • 2019-05-26
    • 1970-01-01
    • 2014-06-15
    • 1970-01-01
    • 2013-03-04
    • 1970-01-01
    • 1970-01-01
    • 2018-04-26
    相关资源
    最近更新 更多