【问题标题】:How to SELECT all rows within a certain date/time range with a certain timestamp step size in MySQL?如何在 MySQL 中以特定时间戳步长选择特定日期/时间范围内的所有行?
【发布时间】:2019-08-08 03:58:33
【问题描述】:

我有一个包含传感器数据的表,其中有一列 timestamp 包含进行传感器测量的时间的 unix 时间戳。 现在我想SELECT 在特定日期/时间范围内使用特定时间步长进行所有测量。
我自己想出了第一部分,就像您在下面我发布的代码 sn-p 中看到的那样。

// With $date_start and $date_stop in the format: '2010-10-01 12:00:00'

$result = mysqli_query($connection, "SELECT sensor_1 
                                     FROM sensor_table 
                                     WHERE timestamp >= UNIX_TIMESTAMP($date_start) 
                                       AND timestamp < UNIX_TIMESTAMP($date_stop) 
                                     ORDER BY timestamp");  

现在在 MySQL 中是否有一种方便的方法可以将时间步长包含到同一个 SELECT 查询中?

我的表格包含数月的数千次测量,每 5 秒进行一次测量。

现在假设我想在2010-10-01 12:00:002010-10-02 12:00:00 之间进行SELECT 测量,但在此日期/时间范围内仅SELECT 每10 分钟测量一次? (因为我的表格包含每 5 秒进行一次测量)。

任何聪明的想法如何在单个查询中解决这个问题?
(也非常欢迎其他想法:))

【问题讨论】:

  • 所以您只想要 10 分钟范围内的一个结果?你如何确定哪个是“正确”的? 10 分钟范围内的第一、最后、最高、最低?
  • 不,我实际上想要在 '2010-10-01 12:00:00' 和 '2010-10-02 12:00:00' 之间获取的传感器值(即一整天)但是因为测量值被保存到数据库中,只有 5 秒的时间差,结果太多了。所以我仍然想要一整天的测量值,但时间步长更大(例如,测量值保存到数据库中的是 10 分钟而不是 5 秒)。我可以说得清楚一点吗?如果不是,我尝试用一​​个更好的例子再次解释它。谢谢你的回答:)
  • 我问的是在这 10 分钟的窗口内,有 120 个条目 - 您认为其中哪一个是正确的?第一个,最高的?最低的?
  • 嗯,它会从指定范围内的第一个开始,然后在 10 分钟后下一个。然后在 10 分钟后再次下一个(直到达到 '2010-10-02 12:00:00')。抱歉不够清楚。

标签: mysql sql select timestamp


【解决方案1】:

由于您每 5 秒进行一次测量,$date_start 与第一个匹配测量之间的差异不能大于 4。然后我们每 600 秒进行一次输入(考虑到时钟之间的一些差异......)

SELECT sensor_1 
  FROM sensor_table
 WHERE timestamp >= UNIX_TIMESTAMP($date_start) 
       AND 
       timestamp < UNIX_TIMESTAMP($date_stop) 
       AND
       ((timestamp - UNIX_TIMESTAMP($date_start)) % 600) BETWEEN 0 AND 4 
 ORDER BY timestamp;

【讨论】:

    【解决方案2】:

    它并不优雅,但你可以这样做:

    SELECT s.sensor_1 
    FROM sensor_table s
    WHERE s.timestamp >= UNIX_TIMESTAMP($date_start) AND
          s.timestamp < UNIX_TIMESTAMP($date_stop) AND
          s.timestamp = (SELECT MIN(s2.timestamp)
                         FROM sensor_table s2
                         WHERE s2.timestamp >= 60 * 10 * FLOOR(UNIX_TIMESTAMP(s.timestamp) / (60 * 10)) AND
                               s2.timestamp < s2.timestamp >= 60 * 10 * (1 + FLOOR(UNIX_TIMESTAMP(s.timestamp) / (60 * 10)))
                        )
    ORDER BY timestamp;
    

    这会选择每 10 分钟内的第一个。

    【讨论】:

      【解决方案3】:

      我认为你可以在 plSQL 中使用一个简单的游标

          CREATE TABLE StoreValuesId
          (
            valueId int primary key;
          )
      
          CREATE OR REPLACE procedure_store[date_start date,date_stop date]
          DECLARE date_startUpdated date , date_stopUpdated date , date_diff TIME(7) = '00:10:00'
          IS 
          BEGIN
      SELECT date_start INTO date_startUpdated;
      SELECT date_stop INTO date_stopUpdated;
          IF timestamp BETWEEN date_start and date_stop then
          INSERT INTO StoreValuesId values(timestamp)
      
          date_startUpdated=DATEADD(SECOND, DATEDIFF(SECOND, 0, date_diff), date_startUpdated);
          date_stopUpdated=DATEADD(SECOND, DATEDIFF(SECOND, 0, date_diff), date_stopUpdated);
          END IF
          COMMIT;
          END
      

      然后语法可能是错误的,但我希望你能明白(有一段时间没玩过 sql)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多