Postgres按相似的日期将数据分成组

问题描述 投票:0回答:1

我有一个讲桌人,我会这样叫data_rows

create table if not exists data_rows
(
    id                integer  not null,
    constraint data_rows_to_group
        primary key (id),
    date              date     not null,
    group_id          int, 
    --more fields that are not relevant
);

当我按日期对行进行排序时,如果与前一行的日期差为> 7天,我希望这些行具有新的group_id(可以是另一个time_span,但应将其保持在7天)因此,按日期排序时具有相同group_id的所有行的日期差小于等于7天。例如:

id      date        group id
1      12.01.2019   0
2      15.01.2019   0
3      21.01.2019   0
4      05.02.2019   1
5      08.02.2019   1
6      20.02.2019   2
7      30.02.2019   3
8      30.02.2019   3

((尤其是1和3在同一组中,尽管它们之间的差异> 7,但是在该组中,接下来的两行之间的差异没有> 7)]

我知道如何以程序方式在python或c#或类似语言中执行此操作。但是,如果我可以在postgresql服务器上执行此操作,将非常有用,因为它包含大量数据,并且也将其保持在单个故障点,这也将是一个很好的学习经验。

这是我在C#中的处理方式,因此您了解了我想要的东西:

using System;
using System.Collections.Generic;
using System.Linq;

class DataRows
{
    public int Id { get; set; }
    public DateTime Date { get; set; }
    public int GroupId { get; set; }
}

class GroupMarking
{
    public DataRows[] RowsWithGroupIds(IEnumerable<DataRows> relevantDataRows, TimeSpan betweenSpan)
    {
        var currentGroupId = 0;
        var rows = relevantDataRows.OrderBy(p => p.Date).ToArray();
        rows[0].GroupId = currentGroupId;
        for (var i = 1; i < rows.Length; i++)
        {
            if (rows[i].Date -
                rows[i - 1].Date >= betweenSpan)
            {
                currentGroupId++;
            }
            rows[i].GroupId = currentGroupId;
        }
        return rows;
    }
}

在PostgreSQL中可能吗?我知道Postgres中有Loops。我更喜欢没有循环的解决方案,但是如果没有它们就不可能解决。如何在不退回程序语言的情况下在group_id列中创建ID?

sql postgresql gaps-and-islands
1个回答
2
投票
select id, "date", sum(flag) over (order by "date") as group_id from ( select id, "date", ("date" - lag("date", 1, "date") over (order by "date") > 7)::int as flag from data_rows ) t order by "date"

表达式"date" - lag("date", 1, "date") over (order by "date")计算“当前”行与上一行之间的日期差。然后检查是否大于7天,并将布尔值转换为整数(0,1),以便可以在其上使用外部运行总和。

Online example

(我将无效日期2019-02-30替换为2019-02-28)]]

© www.soinside.com 2019 - 2024. All rights reserved.