2013-06-25 45 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