Запрос исторических данных - PullRequest
2 голосов
/ 16 марта 2011

Я пытаюсь сделать запрос в базе данных 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, поэтому он может быть присоединен к таблице, содержащей объект, который объективно ссылается на

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 ]

2 голосов
/ 16 марта 2011
select  min(date)
from    historical
where   status        =   2 
and     objectid      =   12
and     date > 
  (select max(date) 
    from  historical
    where status <> 2)
2 голосов
/ 16 марта 2011

Есть много способов сделать это, на ум приходят функции окон

Что-то вроде

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

, поэтому проще настроить тестовый набор

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...