2013-06-25 38 views
6

(Tôi không thể nói tiếng Anh rất tốt, nhưng tôi sẽ cố gắng hết sức)MySQL chọn các giá trị riêng biệt theo thứ tự ngày

Tôi có hai bảng.

table1

 
id carid user 
--------------------- 
1 | A001 | user1 
2 | A002 | user1 
3 | A003 | user2 
4 | A002 | user3 

table2

 
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 

tôi cần phải chọn từng registry biệt "carid" từ "user1" lệnh của datetime

Result tôi cần:

 
    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 

Cách tôi thực sự tạo ra là chọn tất cả "carid" từ người dùng mà tôi muốn và chọn từng hàng riêng lẻ thông qua .net.

`SELECT carid FROM table1 where user = “user1”;` 
 
carid 
----- 
A001 
A002 

Sau đó chọn hàng này tôi muốn:

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 

Nhưng tùy thuộc vào số lượng đăng ký "carid của" từ người dùng mà tôi phải làm rất nhiều querys. Tôi không biết nếu nó có thể làm điều này với một SELECT đơn cải tiến cách tôi đang làm, nhưng đó là những gì tôi đã cố gắng:

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; 

Kết quả:

 
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 

Và tôi cũng đã cố gắng này:

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; 

Kết quả:

 
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 

Nhưng kết quả tôi nhận được là sai. Tôi không biết phải làm gì mà không chọn tất cả các hàng, đó là cách chậm hơn so với cách tôi thực sự làm.

Mọi suy nghĩ?

+2

+1 cho câu hỏi được viết tốt bằng dữ liệu bảng và cách bạn cố gắng giải quyết vấn đề của mình. – Taryn

Trả lời

6

Bạn có thể tham gia vào table2 hai lần, một lần để có được những max(datetime) cho mỗi carId và lần thứ hai để có được những latlon gắn liền với carIddatetime:

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

Xem SQL Fiddle with Demo.

truy vấn của bạn với max() được trở về sai latlon giá trị bởi vì bạn chỉ được nhóm bởi carid để MySQL tùy tiện có thể lựa chọn các giá trị cho các cột trong danh sách lựa chọn mà không phải là trong một chức năng tổng hợp hoặc một GROUP BY. Hành vi này là do MySQL's Extensions to GROUP BY.

Từ Documents MySQL:

MySQL mở rộng việc sử dụng GROUP BY để danh sách lựa chọn có thể tham khảo cột nonaggregated không có tên trong mệnh đề GROUP BY. ... Bạn có thể sử dụng tính năng này để có hiệu suất tốt hơn bằng cách tránh phân loại và nhóm cột không cần thiết. Tuy nhiên, điều này hữu ích chủ yếu khi tất cả các giá trị trong mỗi cột không được phân tách không được đặt tên trong GROUP BY giống nhau cho mỗi nhóm. Máy chủ được tự do chọn bất kỳ giá trị nào từ mỗi nhóm, do đó, trừ khi chúng giống nhau, các giá trị được chọn là không xác định. Hơn nữa, việc lựa chọn các giá trị từ mỗi nhóm không thể bị ảnh hưởng bằng cách thêm mệnh đề ORDER BY. Việc sắp xếp tập hợp kết quả xảy ra sau khi các giá trị đã được chọn, và ORDER BY không ảnh hưởng đến các giá trị mà máy chủ chọn.

Để đảm bảo rằng bạn trả lại giá trị chính xác, bạn sẽ muốn sử dụng truy vấn con tương tự như ở trên.

+0

Cảm ơn bạn đã dành thời gian trả lời. Bằng cách này thực sự hoạt động theo cách tôi muốn, nhưng không may là tôi mất nhiều thời gian hơn cách tôi giải thích. Đánh dấu là câu trả lời. – Sagevalle

+0

@Sagevalle Bạn có bất kỳ chỉ mục nào trên bàn của mình không? – Taryn

+0

Có, trong ** Table1 ** ´carid´ và ´user´, và trong ** Table2 ** ´carid´. – Sagevalle

0

Tôi nghĩ rằng truy vấn sau sẽ hoạt động cho kịch bản của bạn. Tôi đã không cố gắng giống như tôi không có dữ liệu.

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

Hãy cho tôi biết nếu công trình này hoạt động.

+0

Nó không hoạt động. – Sagevalle

Các vấn đề liên quan