简体   繁体   English

如何编写一个SQL查询,该查询将从每分钟更新一次(并使用当前时间)的数据库中获取每小时的记录

[英]How to write an SQL query that will grab hourly records from a database that updates every minute (and uses the current time)

I'm working on a java program that reads from a database that is keeping various measurements of a lake minute by minute. 我正在研究从数据库中读取数据的Java程序,该数据库每分钟都在对湖泊进行各种测量。 I need to write a query that will list each variables by most recent time then skip 1 full hour and display the record at that new time, and repeat that process so I can retrieve the values hourly for the last 48 hours and store them as an array on the java side. 我需要编写一个查询,该查询将按最近时间列出每个变量,然后跳过1个整小时并在该新时间显示记录,然后重复该过程,这样我就可以每小时检索过去48小时的值并将其存储为Java端的数组。 The biggest thing is it needs to be real time. 最大的事情是它必须是实时的。 (The DB records 3120 records each hour) (DB每小时记录3120条记录)

StreamID is that of the sensor, MeasurementID is given to a single measurement, MeasurementValue is the what the sensor returns, and MeasurementTime is using the datetime data type YYYY-MM-DD HH:MM:SS of the measurement StreamID是传感器YYYY-MM-DD HH:MM:SSMeasurementID被赋予单个度量,MeasurementValue是传感器返回的值, MeasurementTime使用度量日期时间数据类型YYYY-MM-DD HH:MM:SS

my current select statement is below, I will mostly likely have to do separate statements for each variable but if I can avoid that I would like to. 我当前的select语句在下面,我很可能不得不为每个变量做单独的语句,但是如果可以避免的话,我想这样做。

SELECT StreamID,MeasurementID,MeasurementValue,MeasurementTime

  FROM measurements

  WHERE StreamID IN (26,27,28,29,30,31,32,33,34,35,14,36,37,38,39,40,
   41,42,43,44,45,46,47,48,49,50,18,13,11,12)

  ORDER BY MeasurementTime DESC, StreamID;

Here I have my reading of the db using result set, I'm not sure how to do multiple queries in a row to ignore "&&result2.next()" 在这里,我使用结果集阅读了数据库,我不确定如何连续执行多个查询以忽略“ && result2.next()”

 while(result.next())//&&result2.next()

 System.out.println(result.getString(1)+"\t"+result.getString(2)
 +"\t"+result.getString(3)+"\t"+result.getString(4)
 +"/t"+result.getString(5)+"\n";


con.close();

I'm not sure I understand exactly what you need to get from the db, but to execute a query hourly you can use a ScheduledExecutorService. 我不确定我是否确切了解您需要从数据库中获取什么,但是要每小时执行一次查询,可以使用ScheduledExecutorService。

    ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
    Runnable task = () -> {
        // Run query
    };
    executor.scheduleAtFixedRate(task, 0, 1, TimeUnit.HOURS);

This will create a new thread that runs the run() method at a fixed rate. 这将创建一个新线程,该线程以固定速率运行run()方法。 The rate is specified by scheduleAtFixedRate(task to run, initial delay (before the first time you run it), delay (between every time you run it), unit). 速率由scheduleAtFixedRate(要运行的任务,初始延迟(首次运行前),延迟(每次运行之间),单位)指定。

For the query you can try using a PreparedStatement so that you can just update the parameters instead of making a new query, thought I'm not completely sure what you want to do on that part, how do you know what IDs to look for? 对于查询,您可以尝试使用PreparedStatement,以便仅更新参数而不是进行新查询,以为我不确定您要在那部分做什么,如何知道要查找的ID?

EDIT: As I understand it, you're trying to get records hourly instead of every minute? 编辑:据我了解,您正在尝试每小时(而不是每分钟)获取记录? The new Date and Time API has some pretty nifty tricks that can help you. 新的日期和时间API有一些漂亮的技巧可以为您提供帮助。

Here's a quick mockup I ran earlier: 这是我之前运行的快速样机:

String sql = "SELECT * FROM measurements ORDER BY Time";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet result = ps.executeQuery();
ArrayList<Integer> values = new ArrayList<>(); // This is where I store the values I want to keep, you can do it w/e way you want
LocalDateTime ldt1;
LocalDateTime ldt2;
// Take the earliest time
result.next(); // You might want to put that in an if() or catch Exceptions
ldt1 = LocalDateTime.parse(result.getString("Date"));
values.add(result.getInt("Value"));
// Increment throught the values until you find one with more than an hour difference with the first one, keep it and change that first one to this new one to continue
while (result.next()) {
    ldt2 = LocalDateTime.parse(result.getString("Date"));
    if (Duration.between(ldt1, ldt2).getSeconds() >= 60*60) {
        values.add(result.getInt("Value"));
        ldt1 = ldt2;
    }
}
System.out.println("values:\n");
System.out.println(values);

My simplified db has theses values: 我的简化数据库具有以下值:

Date                    | Value
2017-11-15T22:32:13.590 | 0
2017-11-15T22:47:13.590 | 1
2017-11-15T23:02:13.590 | 2
2017-11-15T23:17:13.590 | 3
2017-11-15T23:32:13.590 | 4
2017-11-15T23:47:13.590 | 5
2017-11-16T00:02:13.590 | 6
2017-11-16T00:17:13.590 | 7
2017-11-16T00:32:13.590 | 8
2017-11-16T00:47:13.590 | 9
2017-11-16T01:02:13.590 | 10
2017-11-16T01:17:13.590 | 11
2017-11-16T01:32:13.590 | 12
2017-11-16T01:47:13.590 | 13
2017-11-16T02:02:13.590 | 14
2017-11-16T02:17:13.590 | 15
2017-11-16T02:32:13.590 | 16
2017-11-16T02:47:13.590 | 17
2017-11-16T03:02:13.590 | 18
2017-11-16T03:17:13.590 | 19
2017-11-16T03:32:13.590 | 20
2017-11-16T03:47:13.590 | 21
2017-11-16T04:02:13.590 | 22
2017-11-16T04:17:13.590 | 23
2017-11-16T04:32:13.590 | 24
2017-11-16T04:47:13.590 | 25
2017-11-16T05:02:13.590 | 26
2017-11-16T05:17:13.590 | 27
2017-11-16T05:32:13.590 | 28
2017-11-16T05:47:13.590 | 29

And the values ArrayList contains: 值ArrayList包含:

[0, 4, 8, 12, 16, 20, 24, 28]

If you don't have Strings or whatnot you can also make conversions from TimeStamp to LocalDateTime. 如果您没有字符串或其他什么,也可以从TimeStamp转换为LocalDateTime。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM