用于检测累计值何时达到限制的 SQL 查询

时间:2021-06-15 10:42:52

标签: sql postgresql timestamp timescaledb accumulate

鉴于PostgreSQL中的下表

CREATE TABLE my_table (
    time TIMESTAMP NOT NULL,
    minutes INTEGER NOT NULL);

我正在形成一个查询,以检测“分钟”的累计值何时跨越小时边界。例如表中的以下数据:

time             | minutes
-------------------------
<some timestamp> | 55
<some timestamp> | 4

我想知道距离 60(一小时)还有多少分钟。在示例中,答案是 1,因为 55 + 4 + 1 = 60

此外,我想在插入时知道这一点,所以如果我的最后一次插入使累积的分钟数跨越了“小时边界”,我希望它返回布尔值 true。

我的天真尝试,没有插入部分,看起来像这样:

    SELECT
        make_timestamptz(
            date_part('year', (SELECT current_timestamp))::int,
            date_part('month', (SELECT current_timestamp))::int,
            date_part('day', (SELECT current_timestamp))::int,
            date_part('hour', (SELECT current_timestamp))::int,
            0,
            0
        ) AS current_hour,

        SUM(minutes) as sum_minutes
    FROM
        my_table
    WHERE
        sum_minutes >= 60

然后我会取大于 0 的行数表示我们越过了边界。但它是无可救药的不优雅,并且不起作用。这甚至可能吗?是否有可能使其性能有所提高?

我在 Linux 上使用 Timescaledb/PostgreSQL。

2 个答案:

答案 0 :(得分:1)

嗯。 . . insert 并没有真正返回值。但是您可以使用 CTE 进行插入,然后在插入后对值求和:

with i as (
      insert into my_table ( . . . )
          values ( . . . )
          returning *
     )
select ( coalesce(i.minutes, 0) + coalesce(t.minutes, 0) ) > 60
from (select sum(minutes) as minutes from i) i cross join
     (select sum(minutes) as minutes from my_table) t

答案 1 :(得分:1)

INSERT 可能如下所示:

WITH cur_sum AS (
   SELECT coalesce(sum(minutes), 0) AS minutes
   FROM my_table
   WHERE date_trunc('hour', current_timestamp) = date_trunc('hour', time)
)
INSERT INTO my_table (time, minutes)
SELECT current_timestamp, 12 FROM cur_sum
RETURNING cur_sum.minutes + 12 > 60;

此示例在当前时间插入 12 分钟。

相关问题