8

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

我想要的是在给定时间间隔(tmin...tmax)内活动的所有 TrackID 的列表,按它们的开始时间排序,即使该开始时间在时间​​间隔之外

一个小插图可能会有所帮助:

插图

例如:轨道 1 从 t11 到 t12 处于活动状态,这意味着我的表中有很多行 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 的所有行。

当然,我可以在第一步中获取所有活动的 TrackID

SELECT TrackID FROM Tracks WHERE Timestamp BETWEEN tmin AND tmax GROUP BY TrackID;

然后通过单独的查询找到所有这些曲目的开始时间,然后在我的应用程序代码中对它们进行排序。

但我确信有一种方法可以通过一个 SQL 查询来做到这一点。我的表包含数百万行,所以这里的效率是一个问题。

4

4 回答 4

4

看看你的图片 - 你想要的所有范围的结束时间都大于min和开始时间小于max

于 2012-06-01T13:52:27.070 回答
3

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

  1. 趋向 > tmin 和
  2. tstart < tmax

如果这两个条件中的任何一个为真,则应包括轨道。您将需要第二个查询中的曲目列表及其最小值和最大值,然后执行比较:

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
于 2012-06-01T13:56:01.373 回答
2

怎么样:

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;
于 2012-06-01T13:51:25.597 回答
-1

您的第二个查询走在了正确的轨道上,您只需要添加一个ORDER BY子句。

SELECT DISTINCT TrackID 
FROM Tracks 
WHERE Timestamp BETWEEN tmin AND tmax 
GROUP BY TrackID 
ORDER BY Timestamp;
于 2012-06-01T13:51:59.090 回答