1

我有一个数据库,其中包含具有“时间”(整数)和其他一些属性的事件。

例如

CREATE TABLE events (time, attr1, attr2);
INSERT INTO events VALUES (1, 'a', 'foo');
INSERT INTO events VALUES (2, 'b', 'bar');
INSERT INTO events VALUES (4, 'a', 'baz');
INSERT INTO events VALUES (9, 'b', 'quux');
INSERT INTO events VALUES (10, 'c', 'foobar');

现在我想做一个有点复杂的查询:我想找到所有具有表中的下一个事件满足某个条件的属性的事件。例如,我可能想找到满足所有这些条件的所有事件:

  • attr1 == 'a'
  • 下一个事件(由时间字段确定)具有 attr2 == 'bar'

这应该返回时间 1 的事件,而不是时间 4 的事件。或者更复杂的示例是:找到所有满足

  • attr1 == 'a'
  • attr1 == 'c'具有 attr2 == 'foobar'的下一个事件

这将返回时间 1 和 4 的事件。

似乎这应该可以通过某种复杂的嵌套选择来实现,但我还没有弄清楚如何做。

其他注意事项:

  • 我正在使用sqlite。
  • 事件的间隔不规则,因此涉及计算“下一个”事件位置的策略将不起作用。
  • 我知道这些查询将在查询优化器上被谋杀,这没关系。
  • 我知道如何通过执行多个选择 + 非 SQL 逻辑来做到这一点,但我更愿意使用纯 SQL 来做到这一点,因为它嵌入在更大的查询生成系统中。我需要能够生成这种形式的查询,结合其他约束等,这不仅仅是我将编写一次并完成的单个查询。
4

2 回答 2

2

ORDER BY您可以通过组合and找到在某个特定时间后的下一条记录LIMIT

SELECT *
FROM events
WHERE time > 1
ORDER BY time
LIMIT 1

通过在子查询中使用它,您可以从下一条记录中查找值。

您的第一个查询可以这样实现:

SELECT *
FROM events AS e2
WHERE attr1 = 'a'
  AND (SELECT attr2
       FROM events
       WHERE time > e2.time
       ORDER BY time
       LIMIT 1) = 'bar'

您的第二个查询可以这样实现(附加条件属于WHERE子查询):

SELECT *
FROM events AS e2
WHERE attr1 = 'a'
  AND (SELECT attr2
       FROM events
       WHERE attr1 = 'c'
         AND time > e2.time
       ORDER BY time
       LIMIT 1) = 'foobar'

使用列上的索引可以更快地进行子查询查找time

于 2013-09-30T13:29:09.680 回答
1
select * from events a
where exists 
  (
   select * from events c where c.time =
  (select min(b.time) from events b where b.time > a.time)--next_event
   and c.attr2 = 'bar'
  )
and a.attr1 = 'a'

应该是您的第一个查询。它返回时间 1。

http://sqlfiddle.com/#!2/63baf/12

第二个可能是:

select * from events a
where exists 
  (
   select * from events c where c.time =
  (select min(b.time) from events b where b.time > a.time and attr1 = 'c')
   and c.attr2 = 'foobar'
  )
and a.attr1 = 'a'

但它返回时间 1 和 4(与您期望的不同,但这两个行都符合您的条件)

http://sqlfiddle.com/#!2/63baf/15

希望这可以帮助

尼古拉斯

于 2013-09-30T12:44:05.967 回答