2013-06-25 24 views
6

(我不会说英语很好,但我会尽我所能)MySQL选择不同的值按日期排序

我有两张表。

表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 

,我需要选择每一个不同的注册表从 “用户1”, “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的”从用户我必须做很多querys的。 我不知道这是否是可能的一个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 

但是我得到的结果是错误的。 我不知道如何选择所有的行,这比我真正做到的方式要慢一些。

有什么想法?

+2

对表格数据写得很好的问题以及您如何尝试解决您的问题+1。 – Taryn

回答

6

可以联接table2两次,第一次拿到max(datetime)每个carId和第二拿到lat并与carIddatetime相关lon

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'; 

SQL Fiddle with Demo

您的查询与max()返航错误latlon值,因为你只用carid分组因此MySQL可以任意选择在选择列表中没有的聚合函数或GROUP BY列中的值。此行为归因于MySQL's Extensions to GROUP BY

从MySQL的文档:

MySQL的扩展使用GROUP BY的,这样的选择列表可参考在GROUP BY子句中未命名的非聚合列。 ...您可以使用此功能通过避免不必要的列排序和分组来获得更好的性能。但是,这非常有用,因为每个未在GROUP BY中命名的非聚合列中的所有值对于每个组都是相同的。服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选值是不确定的。此外,每个组的值的选择不能通过添加ORDER BY子句来影响。结果集的排序在选择值后发生,而ORDER BY不影响服务器选择的值。

为了确保您返回正确的值,您需要使用与上述类似的子查询。

+0

感谢您花时间回答。这种方式的确按照我想要的方式工作,但不幸的是,比我解释的方式花费更多的时间。标记为答案。 – Sagevalle

+0

@Sagevalle你的桌子上是否有索引? – Taryn

+0

是的,在** Table1 **'carid'和'user'中,在** Table2 **'carid'中。 – Sagevalle

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); 

让我知道这是否工作。

+0

它没有工作。 – Sagevalle