0

我有 2 个表格,车辆的描述和 lat/long 的 itorical 表格,因为它们移动。两个表都有一个 Id 键(PK 和 FK)。

我的 SELECT 看起来像这样

SELECT vehicles.id,          vehicles.description, vehicles.type, 
       positions.time_stamp, positions.latitude,   positions.longitude

       FROM         vehicles
       INNER JOIN   positions 
       ON           vehicles.id=positions.id

我想订购和限制它,以便它只显示为每辆车报告的最新 poisiotn 的连接值。

我怎样才能做到这一点?谢谢


[更新] 我创建了这个 SqlFiddle 演示,它没有给出想要的结果。

我想我需要一些类似的东西

   ORDER BY     positions.time_stamp DESC
   LIMIT SELECT COUNT(*) FROM vehicles

如果只有那是有效的语法:-/


[进一步更新]对于那些关心thingsg执行顺序的人:

  1. 不会从positions表中删除,只有插入
  2. 每辆车每隔几分钟插入一次
  3. 我可以忍受奇怪的异常光点,我预计这将是非常罕见的
  4. 车辆的细节不太可能发生变化,我所做的只是添加新位置

这会让事情变得更容易吗?

4

5 回答 5

6

如果(id, time_stamp)是唯一的,即同一辆车没有两行和相同的时间戳,您可以使用内联视图(mysql 将其称为派生表)来获取每辆车的最新时间戳。然后,您可以将该派生表连接到位置表,以获取其他列,如下所示:

SELECT v.id
     , v.description
     , v.type
     , p.time_stamp
     , p.latitude
     , p.longitude
  FROM ( SELECT MAX(l.time_stamp) AS max_time_stamp
              , l.id
           FROM positions l
          GROUP BY l.id
       ) m
 JOIN positions p
    ON p.id = m.id
   AND p.time_stamp = m.max_time_stamp
  JOIN vehicles v
    ON v.id = p.id

您可以仅在内联视图中运行该查询(m在上面的查询中分配了别名,以验证这是否返回了每辆车的最新时间戳。

如果您希望结果按特定顺序排列,您可以添加 ORDER BY。(此查询有可能为车辆返回多行,如果同一车辆的两(或更多)行出现最新的 time_stamp 值。如果车辆没有重复 time_stamp 值,则不会发生这种情况。)

适当的索引将加快派生表的创建,并加快连接操作回到位置表:

 CREATE INDEX positions_IX1 ON positions (id,time_stamp)

(在其他关系型数据库如 Oracle 和 SQL Server 中,我们可以使用“分析函数”,但 MySQL 尚不支持这些类型的函数。)

于 2013-04-19T03:55:50.657 回答
1

询问:

SQLFIDDLE示例

SELECT v.id
     , v.description
     , v.type
     , p.time_stamp
     , p.latitude
     , p.longitude
  FROM positions p
  JOIN vehicles v ON v.id = p.id
WHERE p.time_stamp = (SELECT MAX(l.time_stamp)
                      FROM positions l
                      WHERE l.id = p.id)

结果:

| ID | DESCRIPTION | TYPE |                   TIME_STAMP | LATITUDE | LONGITUDE |
---------------------------------------------------------------------------------
|  1 |     Trabant |  car | April, 19 2013 13:43:12+0000 | 26.77994 | 402.46261 |
|  2 |    Bus # 42 |  bus | April, 19 2013 13:43:12+0000 | 32.77994 |  48.46261 |
于 2013-04-19T13:53:57.893 回答
1
SELECT v.id, v.description, v.type, p.time_stamp, p.latitude, p.longitude
FROM vehicles v
INNER JOIN positions p ON v.id = p.id
GROUP BY v.id
ORDER BY p.time_stamp DESC
于 2013-04-19T03:34:19.603 回答
1
SELECT v.id, v.description, v.type,
       cur_pos.time_stamp, cur_pos.latitude, cur_pos.longitude
FROM vehicles AS v,
(
    SELECT p.time_stamp, p.latitude, p.longitude
    FROM positions AS p
    WHERE p.id = v.id
    ORDER BY p.time_stamp DESC
    LIMIT 1
) AS cur_pos

可能还有其他方法可以做到这一点;以下是一种尝试,但正如下面的评论中所指出的,它并没有按照原始海报的要求进行。我保留它仅供参考:

SELECT v.id, v.description, v.type,
       MAX(p.time_stamp), p.latitude, p.longitude
FROM vehicles AS v INNER JOIN positions AS p ON v.id = p.id
GROUP BY v.id, v.description, v.type, p.latitude, p.longitude
于 2013-04-19T03:40:28.647 回答
0

试试这个查询 -

SELECT
  v.id, v.description, v.type, t.id, t.time_stamp, t.latitude, t.longitude
FROM vehicles v
  JOIN (
    SELECT t1.*, COUNT(*) num FROM positions t1
      LEFT JOIN positions t2
        ON t2.id = t1.id AND t2.time_stamp >= t1.time_stamp
    GROUP BY
      t1.id, t1.time_stamp
    ) t
  ON v.id = t.id
WHERE
  num <= 2;

+----+-------------+------+----+---------------------+-----------+-----------+
| id | description | type | id | time_stamp          | latitude  | longitude |
+----+-------------+------+----+---------------------+-----------+-----------+
|  1 | Trabant     | car  |  1 | 2013-04-25 09:45:39 | 161.77994 | 102.46261 |
|  1 | Trabant     | car  |  1 | 2013-04-25 09:45:40 | 261.77994 | 402.46261 |
|  2 | Bus # 42    | bus  |  2 | 2013-04-25 09:45:39 | 221.77994 |  88.46261 |
|  2 | Bus # 42    | bus  |  2 | 2013-04-25 09:45:40 | 321.77994 |  48.46261 |
+----+-------------+------+----+---------------------+-----------+-----------+

更改num最后一行中的值以选择每组所需的输出记录数。给定的示例每组输出 2 条记录。

于 2013-04-25T07:01:01.410 回答