mysql - 从时间线到时间戳表的 SQL 连接类别

标签 mysql sql join

考虑以下结构:

create table timestamps(id int, stamp timestamp);
insert into timestamps values
(1,'2017-10-01 10:05:01'),
(2,'2017-10-01 11:05:01'),
(3,'2017-10-01 12:05:01'),
(4,'2017-10-01 13:05:01');

create table category_timeline(begin timestamp,end timestamp, category varchar(100));
insert into category_timeline values
('2017-10-01 10:01:03','2017-10-01 12:01:03','Cat1'),
('2017-10-01 12:01:03','2017-10-01 12:42:43','Cat3'),
('2017-10-01 12:42:43','2017-10-01 14:01:03','Cat2');

相同的Sqlfiddle:SQL Fiddle

我有两个表,一个 (timestamps) 包含时间戳,另一个 (category_timeline) 包含类别时间线,也就是说,我们假设 中的记录>category_timeline 形成一个连续的不重叠的时间线,为每个时间段分配一个类别。

我想将类别分配给 timestamps 表,结果是:

| id |                stamp | category |
|----|----------------------|----------|
|  1 | 2017-10-01T10:05:01Z |     Cat1 |
|  2 | 2017-10-01T11:05:01Z |     Cat1 |
|  3 | 2017-10-01T12:05:01Z |     Cat3 |
|  4 | 2017-10-01T13:05:01Z |     Cat2 |

这是以下查询的结果:

SELECT id, stamp, category FROM timestamps ts 
LEFT JOIN category_timeline tl 
ON   ts.stamp >= tl.begin 
AND  ts.stamp < tl.end

但是,一旦表变大,此操作似乎会呈指数级变慢,是否有更好的方法来执行此操作,假设任何时间戳仅落在另一个表中的唯一时间段内。

最佳答案

我建议采用这种方法:

SELECT ts.id, ts.stamp, 
       (SELECT tl.category
        FROM category_timeline tl 
        WHERE tl.end > ts.stamp
        ORDER BY tl.end ASC
        LIMIT 1
       ) as category
FROM timestamps ts ;

确保您在 category_timeline(end,category) 上有索引。

关于mysql - 从时间线到时间戳表的 SQL 连接类别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46514833/

相关文章:

mysql - 查询在 Mysql 中不起作用

PHP 不会重定向

php - 纽约和伦敦之间的时区

mysql - 如何连接 3 个表并在子查询中执行联合?

c# - LINQ 中的左外连接

php - 我可以将 VARCHAR(32) 用于 md5() 值吗?

mysql - 有什么办法连接 MySql 和 PostgreSQL 的表吗?

mysql不同类型的公用表

mysql - 添加日期时间列并插入另一个表上引用的值

c# - 如何通过自定义加入数据集来获取此 Linq 查询?