SQLite3使用时间限制内部联接

时间:2014-04-04 17:44:58

标签: sql join sqlite inner-join

我正在尝试使用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表中找到匹配的条目,是否可以在表中每个条目只返回一个条目最大值。所以预期的结果看起来像这样:

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

这应该如何实现?

1 个答案:

答案 0 :(得分:0)

继上面的评论之后(“明确选择你想要的字段,省略第二个时间戳(你似乎并不感兴趣)”使“重复”行不同,并使用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');