Mysql SQL查询:在给定时间间隔内处于活动状态的所有ID的列表,按其开始时间排序

Mysql SQL查询:在给定时间间隔内处于活动状态的所有ID的列表,按其开始时间排序,mysql,sql,Mysql,Sql,我有一个MySQL表,其中包含轨迹的点x/y坐标。每行包含TrackID、时间戳以及该轨迹在给定时间点的X和Y位置 我想要的是在给定时间间隔tmin…tmax期间处于活动状态的所有TrackID的列表,按其开始时间排序,即使该开始时间在该时间间隔之外 举个小例子也许会有帮助: 例如:从t11到t12,磁道1处于活动状态,这意味着我的表中有许多行ID=1,时间戳从t11到t12 所需的输出将是: TrackID | StartTime --------+----------- 7 |

我有一个MySQL表,其中包含轨迹的点x/y坐标。每行包含TrackID、时间戳以及该轨迹在给定时间点的X和Y位置

我想要的是在给定时间间隔tmin…tmax期间处于活动状态的所有TrackID的列表,按其开始时间排序,即使该开始时间在该时间间隔之外

举个小例子也许会有帮助:

例如:从t11到t12,磁道1处于活动状态,这意味着我的表中有许多行ID=1,时间戳从t11到t12

所需的输出将是:

TrackID | StartTime
--------+-----------
    7   |    t71
    1   |    t11
    2   |    t21
    6   |    t61
我试过这样的方法:

SELECT TrackID, MIN(Timestamp) AS StartTime FROM Tracks WHERE Timestamp BETWEEN tmin AND tmax GROUP BY TrackID ORDER BY StartTime;
然而,在上面的例子中,我没有得到轨道1和7的实际开始时间,因为时间戳小于tmin的所有行都不被考虑

当然,在第一步中,我可以使用

SELECT TrackID FROM Tracks WHERE Timestamp BETWEEN tmin AND tmax GROUP BY TrackID;
然后通过单独的查询找到所有这些曲目的开始时间,然后在我的应用程序代码中对它们进行排序

但我相信有一种方法可以通过一个SQL查询来实现这一点。我的表格包含数百万行,因此效率是这里的一个问题。

如何:

SELECT TrackID, MIN(Timestamp) AS StartTime FROM Tracks WHERE EXISTS(
    SELECT *
    FROM Tracks
    WHERE Timestamp BETWEEN tmin AND tmax)
GROUP BY TrackID ORDER BY StartTime;
我认为这样更好:

SELECT SQUERY.TrackID, MIN(SQUERY.Timestamp) AS StartTime FROM (
    SELECT *
    FROM Tracks
    WHERE Timestamp BETWEEN tmin AND tmax) AS SQUERY
GROUP BY SQUERY.TrackID ORDER BY SQUERY.StartTime;
好的,我确定现在就是这样了:p

SELECT TrackID, MIN(Timestamp) AS StartTime FROM Tracks WHERE TrackID IN (
    SELECT TrackID
    FROM Tracks
    WHERE Timestamp BETWEEN tmin AND tmax)
GROUP BY TrackID ORDER BY StartTime;

您的第二个查询是正确的,您只需要添加一个ORDERBY子句


看看你的图片-所有你想要的范围的结束时间都大于最小值,开始时间都小于最大值。

一种思考方法是构建逻辑来处理图表中的四种特殊情况。这两条规则应该足够了

倾向>tmin和 tstart
SELECT T.TrackID
  FROM (SELECT TrackID, MIN(Timestamp) AS StartTime, MAX(Timestamp) AS EndTime
        FROM Tracks GROUP BY TrackID) T
 WHERE T.EndTime > tmin AND T.StartTime < tmax

甚至开始时间都在外面,那么结束时间呢。。。您想要相同的行为吗?我不关心此应用程序中的完成时间。是否可能开始时间和结束时间都在tmin和tmax之外,并且tmin和tmax之间没有时间戳?如果是这样,那么在这种情况下,您的第二个查询将为假阴性。@mellamokb:说得好!与轨道的采样间隔相比,间隔tmin…tmax较大。因此,这永远不应该是一个问题。+1好问题,好解释…@mellamokb我已经纠正了错误-只是忘了写,开始时间不到…@mellamokb既然你已经提出了你的问题,那么写一个查询就没有意义了:-听起来很有希望。我会在星期一检查!我刚意识到这并不完全正确。您需要向子查询中的表添加别名,并将其链接到主表。我可以在SQL Server中执行此操作,但我会首先检查它是否与MySQL中的相同。这与我删除的解决方案非常相似,因为我注意到了一件事,我在您的回答中也注意到了这一点。这行不通。想一想:如果t1在t的某一时刻被包括在范围内,那么在给定的时间间隔之外,它的开始时间和结束时间又是怎样的呢?它将被列出,并且开始时间可以更小!您的上一个解决方案适用于小数据集,但在我原来的大数据集上,我在600秒后遇到2013年的连接丢失错误。我想这是个超时问题。mellamokbs解决方案在我的原始数据集上耗时40秒。是不是你的解决方案慢了那么多?为什么呢?@RobertHegner:这部分取决于你定义了什么索引,以及数据集的密度,例如,一条磁道上有多少个时间戳。我的解决方案提取每个轨迹的最小值和最大值,通过适当的表优化,这两个值可以非常快,而bukko的解决方案提取范围内的每个时间戳,在他的子查询中可能有数百行。如果你搜索一个非常窄的tmin-tmax,也就是说,在这个范围内,每条音轨的时间戳不超过一到两个,bukko的解决方案在这种情况下可能会更快。我想用这种方法,我会得到错误的1和7的开始时间。但我会在周一检查。这会给你你想要的,我想要的是在给定时间间隔tmin…tmax内活动的所有TrackID的列表,按它们的开始时间排序,即使开始时间在时间间隔之外。SELECT/WHERE返回在开始和结束之间具有关联时间戳的TrackID列表,然后按最小时间戳排序。我的查询中没有该列表,但您可以选择t.StartTime以获取开始时间,并按t.StartTime排序以按曲目的开始时间排序。
SELECT T.TrackID
  FROM (SELECT TrackID, MIN(Timestamp) AS StartTime, MAX(Timestamp) AS EndTime
        FROM Tracks GROUP BY TrackID) T
 WHERE T.EndTime > tmin AND T.StartTime < tmax