SQL postgres查询检查以前的匹配索引

时间:2016-03-09 22:15:54

标签: postgresql

我的表跟踪事件变量和状态变量的变化。我希望能够轻松地进行查询,只有当那时的状态变量满足某个条件时才会发生事件。我遇到的问题是事件和状态的时间戳不完全对齐。相反,应检查具有相对于事件时间戳的最新时间戳的状态变量条目。我可以将所有状态变量附加到我的所有事件条目中,但这会使我的数据库变大许多倍。

我的问题是,是否有更有效的方法来进行以下查询。理想情况下,我认为,我希望将状态变量中的时间戳编入索引,以便可以使用其声明值中的任何值访问它,直到下一个时间戳。时间戳严格按升序排列。

编辑:以下是包含的示例表。

CREATE TABLE event
(
  tickstamp integer NOT NULL,
  value integer,
  CONSTRAINT event_pkey PRIMARY KEY (tickstamp)
);

INSERT INTO event VALUES
  (121, 100),
  (152, 75),
  (194, 150);

Create TABLE state
(
  tickstamp integer NOT NULL,
  value integer,
  CONSTRAINT state_pkey PRIMARY KEY (tickstamp)
);

INSERT INTO state VALUES
  (0, 30),
  (160, 95);

SELECT * FROM event, state
WHERE state.value > 50 AND state.tickstamp = (
    SELECT tickstamp FROM state WHERE tickstamp <= event.tickstamp ORDER BY tickstamp DESC LIMIT 1);

真的,我在这里关心的是过滤事件,以便state.value&gt;当事件发生时为50,这对于event中的第三个条目仅适用,但我必须做一个子查询以匹配tickstamps。

2 个答案:

答案 0 :(得分:0)

SELECT * FROM event, state
WHERE state.value > 50 AND state.tickstamp = (
    SELECT MAX(tickstamp) FROM state WHERE tickstamp <= event.tickstamp);

当然,如果tickstamp没有编入索引,它可能仍然需要一个表扫描。更好的解决方案是将自动递增的字段作为索引并查找最大值

答案 1 :(得分:0)

我能够使用postgres范围类型来解决这个问题。

CREATE TABLE event
(
  tickstamp int8range NOT NULL,
  value integer,
  CONSTRAINT event_pkey PRIMARY KEY (tickstamp)
);

INSERT INTO event VALUES
  ('[121,152)', 100),
  ('[152,194)', 75),
  ('[194,)', 150);

Create TABLE state
(
  tickstamp int8range NOT NULL,
  value integer,
  CONSTRAINT state_pkey PRIMARY KEY (tickstamp)
);

INSERT INTO state VALUES
  ('[0,160)', 30),
  ('[160,)', 95);

SELECT * FROM event, state
WHERE state.value > 50 AND event.tickstamp <@ state.tickstamp;