查询历史数据

时间:2011-03-16 09:42:30

标签: sql postgresql

我正在尝试在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。我想获得当前时间间隔的第一个日期。

有人能告诉我如何构建此查询或方法吗?

感谢。


UPDATE 根据@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

2 个答案:

答案 0 :(得分:2)

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

这样的东西
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

因此设置测试用例更容易

答案 1 :(得分:2)

select  min(date)
from    historical
where   status        =   2 
and     objectid      =   12
and     date > 
  (select max(date) 
    from  historical
    where status <> 2)