SQL-比较连续记录

时间:2019-01-20 13:46:58

标签: sql sqlite

我有一个名为schedules的表,用于管理游戏中NPC的位置,如以下示例所示;

NPC    Location      Activity   Time
-------------------------------------
1      Village       Roaming    1000
2      Forest        Hunting    1100
3      Mill          Working    1000
1      Castle        ENTER      1100
1      Castle        Roaming    1100
1      Castle        Working    1200

为此,NPC 1在上午10点漫游到城堡,在上午11点进入并漫游城堡,然后在下午12点在城堡工作。

在地图加载中,我运行一条SQL语句以获取NPC在您当前位置产生的时间列表;

SELECT * FROM schedules WHERE Activity='ENTER' AND Location='my location'

但是我想知道是否有可能通过删除所有ENTER条目并仅比较连续Location记录之间的Time来运行语句来查看NPC何时进入清理状态代替。

我是否只需要遍历每个NPC的每个条目并比较当前位置和先前位置,并标记变化的位置?

2 个答案:

答案 0 :(得分:1)

Window函数(在Sqlite 3.25和更高版本中可用)是您的朋友:

CREATE TABLE npcs(id INTEGER, location TEXT, state TEXT, time INTEGER);
INSERT INTO npcs VALUES(1,'Village','Roaming',1000);
INSERT INTO npcs VALUES(2,'Forest','Hunting',1100);
INSERT INTO npcs VALUES(3,'Mill','Working',1000);
INSERT INTO npcs VALUES(1,'Castle','ENTER',1100);
INSERT INTO npcs VALUES(1,'Castle','Roaming',1100);
INSERT INTO npcs VALUES(1,'Castle','Working',1200);
SELECT *
FROM (SELECT id, location
           , lag(location, 1) OVER (PARTITION BY id ORDER BY time) AS prev_location
           , state, time
      FROM npcs)
WHERE location != prev_location
ORDER BY id, time;

产生

id          location    prev_location  state       time      
----------  ----------  -------------  ----------  ----------
1           Castle      Village        ENTER       1100      

答案 1 :(得分:0)

可以做您想做的事。在最新版本的MySQL中,您将使用lag()。早期版本将需要诸如相关子查询之类的东西。

但是,我不建议这样做。您的应用程序关心“ ENTER”。将事实直接存储在数据中是获取此信息的最有效方法。您可能有不包含它的原因(这些原因未在问题中提及)。从简单性能的角度来看,为澄清代码和简化查询而在表中增加一些额外的行可能是值得的。