历史数据查询

发布于 2024-10-21 23:12:43 字数 1118 浏览 2 评论 0原文

我正在尝试在 postgresql 数据库中进行查询,但我不知道如何进行查询。我有一个历史表,用于存储对象的状态、日期和其他数据。像这样的事情:

id objectid    date    status    ....
----------------------------
9  12          date1   2
8  12          date2   2
7  12          date3   2    <-- This is the date where the last status was set
6  12          date4   1
5  12          date5   1
4  12          date6   6
3  12          date7   6
2  12          date8   2
1  12          date9   2

我需要获取系统中所有对象(objectid)设置当前状态(为每个对象设置的最后一个状态)的日期。因此,在示例中(我只包含了对象 12 的信息以进行简化),如果它们按时间顺序排序(date9 是最旧的,date1 是最早的),则当前状态为 2,我想获取 date3,即该状态是最后一次设置。请注意,之前设置了状态 2,但随后它更改为 6、1,然后再次更改为 2。我想获取当前间隔中的第一个日期。

谁能告诉我如何构造这个查询或要走的路?

谢谢。


根据@Unreason回答进行更新查询,以便它可以连接到包含objectid引用的对象的表

SELECT objectid, max(date)
FROM (
    SELECT objectid, status, date, lag(status) OVER window1, last_value(status) OVER window1 last_status
    FROM historical
    WINDOW window1 AS ( PARTITION BY objectid ORDER BY date) 
    ) x 
WHERE (status <> lag OR lag IS NULL)
AND status = last_status
GROUP BY objectid

I'm trying to make a query in a postgresql database but I can't figure out how the way to make it. I have a historical table which stores the status of an object, the date and other data. Something like this:

id objectid    date    status    ....
----------------------------
9  12          date1   2
8  12          date2   2
7  12          date3   2    <-- This is the date where the last status was set
6  12          date4   1
5  12          date5   1
4  12          date6   6
3  12          date7   6
2  12          date8   2
1  12          date9   2

I need to get the date where the current status (the last one set for each object) has been set for all the objects in the system (objectid). So in the example (I have only included info for the object 12 to symplify) if they are ordered chronologically (date9 is the oldest and date1 is the earliest) the current status is 2 and I want to get date3 which is hen this status was set for the last time. Notice that status 2 was set earlier, but then it changed to 6, 1 and then to 2 again. I want to get the first date in the current interval.

Can anyone tell me how to construct this query or the way to go?

Thanks.


UPDATE query accoring to @Unreason answer so it could be joined to the table which contains the object which objectid references to

SELECT objectid, max(date)
FROM (
    SELECT objectid, status, date, lag(status) OVER window1, last_value(status) OVER window1 last_status
    FROM historical
    WINDOW window1 AS ( PARTITION BY objectid ORDER BY date) 
    ) x 
WHERE (status <> lag OR lag IS NULL)
AND status = last_status
GROUP BY objectid

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

星軌x 2024-10-28 23:12:43

有很多方法可以做到这一点,我想到了窗口函数

类似

SELECT max(date)
FROM (
      SELECT status, date, lag(status) OVER window1, last_value(status) OVER window1 last_status
      FROM historical
      WHERE objectid = 12
      WINDOW window1 AS ( ORDER BY date) 
      ) x 
WHERE (status <> lag OR lag IS NULL)
      AND status = last_status;

注释:

  • 应避免使用关键字作为字段名称(例如滞后和日期)
  • 还有许多其他方法可以编写此查询,
  • 目前它适用于一个对象(objectid = 12),但可以对其进行修改以返回每个对象的最后状态日期

编辑
测试数据

CREATE TABLE historical (
    id integer,
    objectid integer,
    date date,
    status integer
);

INSERT INTO historical VALUES (1, 12, '2000-01-01', 2);
INSERT INTO historical VALUES (2, 12, '2001-01-01', 2);
INSERT INTO historical VALUES (3, 12, '2002-01-01', 6);
INSERT INTO historical VALUES (4, 12, '2003-01-01', 6);
INSERT INTO historical VALUES (5, 12, '2004-01-01', 1);
INSERT INTO historical VALUES (6, 12, '2005-01-01', 1);
INSERT INTO historical VALUES (7, 12, '2006-01-01', 2);
INSERT INTO historical VALUES (8, 12, '2007-01-01', 2);
INSERT INTO historical VALUES (9, 12, '2008-01-01', 2);

将来您可能想要发布结果,

pg_dump -t table_name --inserts

以便更轻松地设置测试用例

There are many ways to do this, windowing functions come to mind

Something like

SELECT max(date)
FROM (
      SELECT status, date, lag(status) OVER window1, last_value(status) OVER window1 last_status
      FROM historical
      WHERE objectid = 12
      WINDOW window1 AS ( ORDER BY date) 
      ) x 
WHERE (status <> lag OR lag IS NULL)
      AND status = last_status;

Notes:

  • using keywords as field names (such as lag and date) should be avoided
  • there are many other ways to write this query
  • currently it works for one object (objectid = 12), but it could be modified to return the date of last status for each object

EDIT
Test data

CREATE TABLE historical (
    id integer,
    objectid integer,
    date date,
    status integer
);

INSERT INTO historical VALUES (1, 12, '2000-01-01', 2);
INSERT INTO historical VALUES (2, 12, '2001-01-01', 2);
INSERT INTO historical VALUES (3, 12, '2002-01-01', 6);
INSERT INTO historical VALUES (4, 12, '2003-01-01', 6);
INSERT INTO historical VALUES (5, 12, '2004-01-01', 1);
INSERT INTO historical VALUES (6, 12, '2005-01-01', 1);
INSERT INTO historical VALUES (7, 12, '2006-01-01', 2);
INSERT INTO historical VALUES (8, 12, '2007-01-01', 2);
INSERT INTO historical VALUES (9, 12, '2008-01-01', 2);

In future you might want to post results of your

pg_dump -t table_name --inserts

so it is easier to setup a test case

待天淡蓝洁白时 2024-10-28 23:12:43
select  min(date)
from    historical
where   status        =   2 
and     objectid      =   12
and     date > 
  (select max(date) 
    from  historical
    where status <> 2)
select  min(date)
from    historical
where   status        =   2 
and     objectid      =   12
and     date > 
  (select max(date) 
    from  historical
    where status <> 2)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文