PostgreSQL动态date_trunc函数精确舍入到给定的时间戳

时间:2019-01-04 14:11:14

标签: postgresql

我正在使用内置的PostgreSQL函数date_trunc()来汇总时间窗口,如下所示:

exports.register = (req, res) => {
  let newUser = new User({
    firstName: req.body.firstName,
    lastName: req.body.lastName,
    email: req.body.email.toLowerCase(),
    username: req.body.username.toLowerCase(),
    password: req.body.password,
    dob: req.body.dob,
    gender: req.body.gender
  });

  User.addUser(newUser, (err, user) => {
    if (err) {
      res.json({ success: false, msg: 'Failed to register user' });
    } else {
      res.json({ success: true, msg: 'User registered' });
    }
  });
};

结果是这样的:

SELECT max(time) as time, 
COUNT(*) as ticks 
FROM sensorticks 
WHERE time between (TIMESTAMP'2019-01-04 00:15:00') AND (TIMESTAMP'2019-01-04 14:15:00') 
GROUP BY date_trunc('hour', time)
ORDER BY time desc;

但是我不想切断第一个窗口。我需要从14:15开始(14:15、13:15等)的动态时间窗口。它应该看起来像这样:

time                        ticks
2019-01-04 14:14:59         892
2019-01-04 13:59:59         3575
2019-01-04 12:59:59         3552
2019-01-04 11:59:59         3560
2019-01-04 10:59:59         2671

我该怎么做?

1 个答案:

答案 0 :(得分:1)

查询的时间窗口似乎取决于public class SListTest { static Node create(int n) { Node tmp = new Node(); for(int i = 1; i < n; ++i) { Node p = new Node(); p.data = i; p.next = tmp; tmp = p; } return tmp; } static double sum(Node x) { double tmp = 0; while(x != null) { tmp += x.data; x = x.next; } return tmp; } static double sums(Node x, int n) { double tmp = 0; for(int i = 0; i < n; ++i) tmp += sum(x); return tmp / n; } public static void echo(String s) { System.out.println(s); System.out.flush(); } public static void main(String[] args) { echo("Started"); Node p = create(1000 * 1000 * 100); echo("Created"); double tmp = sums(p, 100); System.out.printf("%f\n", tmp); echo("Finished"); } } 子句中出现的上限。由于现在是凌晨15点,因此您可以尝试将时间提前45分钟进行汇总:

WHERE

但是上面的查询仍然有问题,因为显示的时间可能仍然不正确。另外,可能缺少一些时隙,但您仍可能要报告它们。要解决此问题,我们可以尝试使用日历表:

SELECT
    MAX(time) AS time, 
    COUNT(*) AS ticks 
FROM sensorticks 
WHERE time BETWEEN (TIMESTAMP'2019-01-04 00:15:00') AND (TIMESTAMP'2019-01-04 14:15:00') 
GROUP BY date_trunc('hour', time + interval '45 minutes')
ORDER BY time DESC;

然后,我们可以使用原始查询连接到此日历表:

WITH calendar AS (
    SELECT TIMESTAMP '2019-01-04 14:00:00' AS ts, TIMESTAMP '2019-01-04 14:14:59' AS display UNION ALL
    SELECT TIMESTAMP '2019-01-04 13:00:00', TIMESTAMP '2019-01-04 13:14:59' UNION ALL
    SELECT TIMESTAMP '2019-01-04 12:00:00', TIMESTAMP '2019-01-04 12:14:59' UNION ALL
    SELECT TIMESTAMP '2019-01-04 11:00:00', TIMESTAMP '2019-01-04 11:14:59' UNION ALL
    SELECT TIMESTAMP '2019-01-04 10:00:00', TIMESTAMP '2019-01-04 10:14:59'
)