繁体   English   中英

如何根据上次修改时间按日期和类别对记录进行分组?

[英]How to group records by date and category based on last modified time?

我需要根据上次修改时间计算每天和类别(在我的示例中为阶段)的当前金额。

编辑:棘手的部分是,当 id 丢失时,它应该使用它在最后一个日期没有丢失的数量和阶段。

这有点令人困惑,但请查看下面的屏幕截图和示例以获取更多信息。

记录表

在此处输入图像描述

预期结果

在此处输入图像描述

如何阅读此表:

sensor XXX was modified on day 1 to Stage A and Amount 100
sensor XXX was not touched on day 2
sensor XXX was modified on day 2 to Stage B and Amount 150

如果表中只有这个传感器 (XXX),则聚合如下:

Day 1
Stage A: 100
Stage B: 0
Stage C: 0

Day 2 (there's no modified time this day)
Stage A: 100 (uses the amount of previous day)
Stage B: 0
Stage C: 0

Day 3
Stage A: 0
Stage B: 0
Stage C: 100

在下面找到 MRE (PostgreSQL)。

记录表

CREATE TABLE IF NOT EXISTS "Sensors_Modified_Time" (
    "Modified_Time" TIMESTAMP,
    "sensorId" TEXT,
    "Stage" TEXT,
    "Amount" INT
);
INSERT INTO "Sensors_Modified_Time" VALUES
    ('2020-01-01 00:00:00','XXX','A',100),
    ('2020-01-03 00:00:00','XXX','B',150),
    ('2020-01-02 00:00:00','YYY','B',120),
    ('2020-01-04 00:00:00','YYY','C',140),
    ('2020-01-01 00:00:00','ZZZ','B',140),
    ('2020-01-02 00:00:00','ZZZ','B',120),
    ('2020-01-03 00:00:00','ZZZ','B',110);

预期结果

CREATE TABLE IF NOT EXISTS "AggregateByDay" (
    "Date" TIMESTAMP,
    "Stage" TEXT,
    "Amount" INT
);
INSERT INTO "AggregateByDay" VALUES
    ('2020-01-01 00:00:00','A',100),
    ('2020-01-01 00:00:00','B',140),
    ('2020-01-01 00:00:00','C',0),
    ('2020-01-02 00:00:00','A',100),
    ('2020-01-02 00:00:00','B',240),
    ('2020-01-02 00:00:00','C',0),
    ('2020-01-03 00:00:00','A',0),
    ('2020-01-03 00:00:00','B',380),
    ('2020-01-03 00:00:00','C',0),
    ('2020-01-04 00:00:00','A',0),
    ('2020-01-04 00:00:00','B',260),
    ('2020-01-04 00:00:00','C',140);

PS:尽管我尽力了,但我知道标题和整个帖子有点混乱,所以请随时帮助我使其更具可读性。 谢谢!

如果我理解正确,您希望所有日子与所有阶段相结合 - 并且丢失的数据为零。

使用cross join生成行,然后使用left join引入值:

select t.modified_time, s.stage,
       coalesce(sum(smt.amount), 0) as amount
from (select distinct modified_time from Sensors_Modified_Time
     ) t cross join
     (select distinct stage from Sensors_Modified_Time
     ) s left join
     Sensors_Modified_Time smt
     on smt.modified_time = t.modified_time and
        smt.stage = s.stage
group by t.modified_time, s.stage
order by t.modified_time, s.stage;

这不会完全返回问题中指定的值,但我认为这是您真正想要做的。

是一个 db<>fiddle。

编辑:

啊,现在我明白了。 对于每个传感器,您要记住每个阶段的最新值。 然后你想在给定的时间为舞台添加它。 执行此操作的一种方法是横向连接 - 与cross join相结合:

select t.modified_time, s.stage,
       coalesce(smt.amount, 0) as amount
from (select distinct modified_time from Sensors_Modified_Time
     ) t cross join
     (select distinct stage from Sensors_Modified_Time
     ) s left join lateral
     (select sum(amount) as amount
      from (select distinct on (smt.sensorid) smt.*
            from Sensors_Modified_Time smt
            where smt.modified_time <= t.modified_time and
                  smt.stage = s.stage
            order by smt.sensorid, smt.modified_time desc
           ) smt
     ) smt
     on 1=1
order by t.modified_time, s.stage;

我修改了 db<>fiddle 也有这个。

暂无
暂无

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

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