我有两张桌子,车辆的描述和一个lat / long的非理想表格。两个表都有一个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的连接值。
我该怎么做?感谢
[更新]我创建了this SqlFiddle demo,但未提供所需的结果。
我认为我需要的是
ORDER BY positions.time_stamp DESC
LIMIT SELECT COUNT(*) FROM vehicles
如果只是有效的语法: - /
[进一步更新]适用于那些关注thinsg执行顺序的人:
positions
表中没有删除,只有插入这会让事情变得更容易吗?
答案 0 :(得分:6)
如果(id, time_stamp)
是唯一的,即同一车辆和同一time_stamp没有两行,您可以使用内联视图(mysql将其称为派生表)来获取每辆车的最新time_stamp。然后,您可以将该派生表连接到位置表,以获取其他列,如下所示:
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
的别名,以验证这是否为每辆车返回最新的time_stamp。
如果您希望按特定顺序排列结果,可以添加ORDER BY。 (此查询有可能为车辆返回多行,IFF最新的time_stamp值出现在同一车辆的两个(或更多)行上。如果没有为车辆复制time_stamp值,则不会发生这种情况。)
适当的索引将加速派生表的创建,并加速连接操作回到位置表:
CREATE INDEX positions_IX1 ON positions (id,time_stamp)
(在其他关系数据库中,例如Oracle和SQL Server,我们可以使用“分析函数”,但MySQL尚不支持这些类型的函数。)
答案 1 :(得分: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
答案 2 :(得分: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
答案 3 :(得分:1)
查询:
<强> SQLFIDDLEExample 强>
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 |
答案 4 :(得分: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条记录。