【问题标题】:SQL query to detect when accumulated value reaches limitSQL查询检测累积值何时达到限制
【发布时间】:2021-08-31 05:10:38
【问题描述】:

给定 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。

【问题讨论】:

    标签: sql postgresql timestamp timescaledb accumulate


    【解决方案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 分钟。

    【讨论】:

    • 看起来很有希望,但是如果过去 3 小时内没有任何行怎么办?似乎 cur_sum 查询只查看过去一小时内有时间的行。当一个多小时的数据存在差距时,这是我一直在努力解决的问题之一。
    • 我添加了一个coalesce,所以在这种情况下你会得到 0。
    【解决方案2】:

    嗯。 . . 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
    

    【讨论】:

    • 你为什么在这里使用交叉连接?求朋友?
    • @LennartRolland 。 . .相对于什么?您可以在 select 中使用子查询,但 cross join 准确地表达了正在发生的事情。
    • 我现在明白了。只用了几天。先生,您是我书中公认的天才。我不知道我是否会使用它,但它是美丽的东西。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2020-07-24
    • 2016-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多