我正在尝试使用 SQLite3 在具有相似数据的两个表之间形成关联。 这是我到目前为止所拥有的:
CREATE TABLE a (date TEXT, user TEXT, ip TEXT);
CREATE INDEX a_index ON a (date, user, ip);
CREATE TABLE b (date TEXT, ip TEXT);
CREATE UNIQUE INDEX b_index ON b (date, ip);
INSERT INTO a VALUES('2014-03-01 03:15:16', 'a', '127.0.0.1');
INSERT INTO a VALUES('2014-03-01 03:15:18', 'b', '127.0.0.2');
INSERT INTO a VALUES('2014-03-01 03:15:21', 'c', '127.0.0.3');
INSERT INTO a VALUES('2014-03-01 03:15:21', 'd', '127.0.0.4');
INSERT INTO a VALUES('2014-03-01 03:15:29', 'e', '127.0.0.5');
INSERT INTO a VALUES('2014-03-01 03:16:32', 'f', '127.0.0.6');
INSERT INTO b VALUES('2014-03-01 03:15:16', '127.0.0.1');
INSERT INTO b VALUES('2014-03-01 03:15:17', '127.0.0.1');
INSERT INTO b VALUES('2014-03-01 03:15:19', '127.0.0.1');
INSERT INTO b VALUES('2014-03-01 03:15:22', '127.0.0.4');
INSERT INTO b VALUES('2014-03-01 03:16:32', '127.0.0.5');
我知道我可以简单地使用内部联接来组合这两个集合,如下所示:
SELECT *
FROM a
JOIN b ON a.ip = b.ip AND a.date = b.date;
它会返回
2014-03-01 03:15:16|a|127.0.0.1|2014-03-01 03:15:16|127.0.0.1
正如预期的那样。然而,由于时间记录中的时钟漂移。我想匹配任何可能的条目,彼此之间相差+- 3 秒。在本例中,我使用了:
SELECT *
FROM a
JOIN b ON a.ip = b.ip AND a.date BETWEEN DATETIME(b.date, '-3 seconds') AND DATETIME(b.date, '+3 seconds');
这有效,尽管它返回的条目比我想要的多。而不是以下内容:
2014-03-01 03:15:16|a|127.0.0.1|2014-03-01 03:15:16|127.0.0.1
2014-03-01 03:15:16|a|127.0.0.1|2014-03-01 03:15:17|127.0.0.1
2014-03-01 03:15:16|a|127.0.0.1|2014-03-01 03:15:19|127.0.0.1
2014-03-01 03:15:21|d|127.0.0.4|2014-03-01 03:15:22|127.0.0.4
我想知道如果在 b 表中找到匹配的条目,是否可以在 a 表中的每个条目最多只返回一个条目。因此预期的结果将如下所示:
2014-03-01 03:15:16|a|127.0.0.1|2014-03-01 03:15:16|127.0.0.1
2014-03-01 03:15:21|d|127.0.0.4|2014-03-01 03:15:22|127.0.0.4
这应该/如何实现?
最佳答案
根据我上面的评论(“显式选择您想要的字段,省略第二个时间戳(无论如何您似乎对此都不感兴趣)”,这会使“重复”行不同,并使用 SELECT DISTINCT 所以您只能获得唯一的行。”),您可以尝试以下操作:
SELECT DISTINCT a.date, a.user, a.ip
FROM a JOIN b ON a.ip = b.ip
AND a.date
BETWEEN DATETIME(b.date, '-3 seconds')
AND DATETIME(b.date, '+3 seconds');
关于SQLite3限制内连接使用时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22869553/