选择表格中每分钟的第一个值

时间:2015-02-13 21:39:41

标签: mysql sql

我一直在努力解决这个问题,也许我的问题是提出正确的搜索查询。我不确定。

无论如何,我遇到的问题是我有一个数据表,每秒都会添加一个新行(想象一下结构{id,timestamp(datetime),value})。我想对 MySQL 执行单个查询以查看表并仅输出每分钟的第一个值。

我考虑过使用LIMIT和datetime> =(分钟开头)进行多次查询,但是我正在收集的数据量很多,因此在数据库中生成数据会更好。单一查询。

示例数据:

id  datetime             value
1   2015-01-01 00:00:00  128
2   2015-01-01 00:00:01  127
3   2015-01-01 00:00:04  129
4   2015-01-01 00:00:05  127
...
67  2015-01-01 00:00:59  112
68  2015-01-01 00:01:12  108
69  2015-01-01 00:01:13  109

我希望结果选择行:

1   2015-01-01 00:00:00  128
68  2015-01-01 00:01:12  108

有什么想法吗?

谢谢!

编辑:忘记添加,数据虽然每秒都不可靠,但在每分钟的第一秒 - 可能是:30或:01而不是:00秒过去

编辑2:一个很好的(绝对不需要回答)将是一个灵活的查询,也可以采取任意数分钟(而不是每分钟一行)

4 个答案:

答案 0 :(得分:1)

SELECT t2.* FROM
( SELECT MIN(`datetime`) AS dt
  FROM tbl
 GROUP BY DATE_FORMAT(`datetime`,'%Y-%m-%d %H:%i')
) t1
JOIN tbl t2 ON t1.dt = t2.`datetime`

SQLFiddle

或者

SELECT * 
FROM tbl 
WHERE dt IN ( SELECT MIN(dt) AS dt
              FROM tbl
              GROUP BY DATE_FORMAT(dt,'%Y-%m-%d %H:%i'))

SQLFiddle

SELECT t1.* 
FROM tbl t1
LEFT JOIN (
  SELECT MIN(dt) AS dt 
  FROM tbl
  GROUP BY DATE_FORMAT(dt,'%Y-%m-%d %H:%i')
) t2 ON t1.dt = t2.dt
WHERE t2.dt IS NOT NULL

SQLFiddle

答案 1 :(得分:0)

在MS SQL Server中我会使用CROSS APPLY,但据我所知MySQL没有它,所以我们可以模仿它。

确保您的datetime列上有索引。

创建一个table of numbers,或者在您的情况下创建一个分钟表。如果你有一个从1开始的数字表,那么在必要的范围内把它变成几分钟是很容易的。

SELECT
  tbl.ID
  ,tbl.`dt`
  ,tbl.value
FROM
  (
    SELECT 
      MinuteValue
      , (
        SELECT tbl.id
        FROM tbl
        WHERE tbl.`dt` >= Minutes.MinuteValue
        ORDER BY tbl.`dt`
        LIMIT 1
        ) AS ID
    FROM Minutes
  ) AS IDs
  INNER JOIN tbl ON tbl.ID = IDs.ID

每分钟找一个时间戳大于分钟的行。我不知道如何在嵌套的SELECT中返回完整行,而不是MySQL中的一列,所以首先我要创建一个包含两列的临时表:Minute和{{1从原始表中,然后显式查找原始表中的行,知道他们的id

SQL Fiddle

我在SQL Fiddle中创建了一个Minutes表,其中包含必要的值以使示例变得简单。在现实生活中,你会有一个更通用的表格。

以下是使用数字表的SQL Fiddle,仅供参考。

在任何情况下,您都需要提前知道您感兴趣的日期/数字的范围。

让它在任何时间间隔内都能正常工作是微不足道的。如果您每5分钟需要一次结果,只需生成一个分钟表,其值不是每1分钟,而是每5分钟。主查询将保持不变。

它可能更有效率,因为在这里你没有将大表连接到自身而你没有在IDs列上进行计算,所以服务器应该能够使用它上面的索引。

我做的例子假设每分钟大表中至少有一行。如果某些分钟可能根本没有任何数据,则需要在datetime子句中添加额外的检查,以确保找到的行仍在该分钟内。

答案 2 :(得分:-1)

select * from table where timestamp LIKE "%-%-% %:%:00"可行。

这与此问题类似:Stack Overflow Date SQL Query Question

修改:这可能会更好:

`选择,date_format(时间戳,'%Y-%m-%d%H:%i')作为the_minute,count() 从表 由the_minute分组 按the_minute排序

此处与此问题类似:mysql select date format

答案 3 :(得分:-1)

我不确定,但你可以试试这个:

SELECT MIN(timestamp) FROM table WHERE YEAR(timestamp)=2015 GROUP BY DATE(timestamp), HOUR(timestamp), MINUTE(timestamp)