(我不能说英语,但我会尽我所能)
我有两张桌子。
表1
id carid user --------------------- 1 | A001 | user1 2 | A002 | user1 3 | A003 | user2 4 | A002 | user3
表2
id carid datetime lat lon ---------------------------------------------------- 1 | A001 | 2013-25-06 10:00:00 | -23.0000 | -46.0000 2 | A002 | 2013-25-06 10:01:00 | -24.3500 | -45.3200 3 | A002 | 2013-25-06 10:02:00 | -24.3800 | -45.3300 4 | A001 | 2013-25-06 10:05:00 | -23.0500 | -46.1000 5 | A003 | 2013-25-06 10:07:00 | -24.3500 | -45.3200 6 | A001 | 2013-25-06 10:10:00 | -23.0700 | -46.1200
我需要从datetime命令的“user1”中选择每个不同的注册表“carid”
我需要的结果:
carid datetime lat lon -------------------------------------------------- A001 | 2013-25-06 10:10:00 | -23.0700 |-46.1200 A002 | 2013-25-06 10:02:00 | -24.3800 |-45.3300
我实际制作的方法是从我想要的用户中选择所有“carid”,然后通过.net单独选择每一行。
`SELECT carid FROM table1 where user = “user1”;`
carid ----- A001 A002
然后选择我想要的行:
SELECT * FROM table2 WHERE car_id='A001' ORDER BY datetime DESC limit 1
SELECT * FROM table2 WHERE car_id='A002' ORDER BY datetime DESC limit 1
但是根据该用户的注册表“carid”的数量,我必须做很多查询。 我不知道是否可以用一个SELECT来改善我的工作方式,但这就是我的尝试:
SELECT car_id, datetime, lat, lon from table1
INNER JOIN table2 on carid = car_id
WHERE user = 'user1'
GROUP BY carid
ORDER BY datetime DESC;
结果:
carid datetime lat lon ------------------------------------------------------ A002 | 2013-25-06 10:01:00 | -24.3500 | -45.3200 A001 | 2013-25-06 10:02:00 | -23.0000 | -46.0000
我也试过这个:
SELECT car_id, MAX(datetime) as datetime, lat, lon from table1
INNER JOIN table2 on carid = car_id
WHERE user = 'user1'
GROUP BY carid
ORDER BY datetime DESC;
结果:
carid datetime lat lon ------------------------------------------------------ A001 | 2013-25-06 10:10:00 | -23.0000 | -46.0000 A002 | 2013-25-06 10:02:00 | -24.3500 | -45.3200
但我得到的结果是错误的。 如果没有选择所有行,我不知道该做什么,这比我真正做的那样慢。
有什么想法吗?
答案 0 :(得分:6)
您可以加入table2
两次,一次获得max(datetime)
carId
,第二次获得与lat
和lon
相关联的carId
datetime
和select t1.carid, t2.datetime, t2.lat, t2.lon
from table1 t1
inner join
(
-- get the lat/lon associated with each carid and max datetime
select t2.carid, t2.datetime, t2.lat, t2.lon
from table2 t2
inner join
(
-- get the max datetime for each carid
select carid, max(datetime) datetime
from table2
group by carid
) d
on t2.carid = d.carid
and t2.datetime = d.datetime
) t2
on t1.carid = t2.carid
where user = 'user1';
:
max()
您使用lat
的查询返回了错误的lon
和carid
值,因为您只是按{{1}}进行分组,因此MySQL可以任意选择列中的值不在聚合函数或GROUP BY中的选择列表。此行为归因于MySQL's Extensions to GROUP BY。
来自MySQL文档:
MySQL扩展了GROUP BY的使用,因此选择列表可以引用GROUP BY子句中未命名的非聚合列。 ...您可以通过避免不必要的列排序和分组来使用此功能来获得更好的性能。但是,当GROUP BY中未命名的每个非聚合列中的所有值对于每个组都相同时,这非常有用。服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选的值是不确定的。此外,添加ORDER BY子句不会影响每个组中值的选择。选择值后会对结果集进行排序,而ORDER BY不会影响服务器选择的值。
为了确保返回正确的值,您将需要使用与上面类似的子查询。
答案 1 :(得分:0)
我认为以下查询应该适用于您的方案。我没有尝试过,因为我没有数据。
SELECT
t1.carid, t2.datetime, t2.lat, t2.lon
FROM
table1 t1 JOIN table2 t2
ON t1.carid = t2.carid AND t1.user='user1'
GROUP BY
carid
HAVING
t2.datetime=MAX(datetime);
让我知道这是否有效。