2013-06-25 25 views
6

(Ich kann Englisch nicht sehr gut sprechen, aber ich werde mein Bestes versuchen)MySQL verschiedene Werte auswählen Reihenfolge nach DatumZeit

Ich habe zwei Tabellen.

tabelle1

 
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 

Ich brauche jede einzelne Registry "carid" von "user1" von Datetime bestellt wählen

Ergebnis ich brauche:

Die Art, die ich tatsächlich mache, ist die Auswahl aller "Carid" von dem Benutzer, den ich will, und die Auswahl jeder Zeile einzeln über .net.

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

Auswahl dann die Zeile Ich mag:

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 

aber abhängig von der Anzahl der Register „carid des“ ich habe zu tun, von dem Benutzer eine Menge querys. Ich weiß nicht, ob es möglich ist, dies zu tun mit einem einzigen SELECT, um die Art und Weise zu verbessern ich tue, aber das ist, was ich versucht habe:

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; 

Ergebnis:

 
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 

Und ich habe auch versucht diese:

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; 

Ergebnis:

 
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 

Aber das Ergebnis ist falsch. Ich weiß nicht, was ich tun soll, ohne alle Zeilen auszuwählen, was langsamer ist als die Art, wie ich es wirklich mache.

Irgendwelche Gedanken?

+2

+1 für eine gut geschriebene Frage mit Tabellendaten und wie Sie versucht haben, Ihr Problem zu lösen. – Taryn

Antwort

6

können Sie auf table2 zweimal beitreten, sobald die max(datetime) für jeden carId zu erhalten und die zweite die lat und lon mit dem carId und datetime verbunden zu bekommen:

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

Siehe SQL Fiddle with Demo.

Ihre Abfrage mit den max() zurückkehren falsch lat und lon Werte, weil man nur durch die carid Gruppierung ist, so kann MySQL willkürlich die Werte für die Spalten in der Auswahlliste auswählen, die nicht in einer Aggregatfunktion oder einem GROUP BY ist. Dieses Verhalten ist auf MySQL's Extensions to GROUP BY zurückzuführen.

aus dem MySQL-Docs:

MySQL erweitert die Verwendung von GROUP BY, so dass die Auswahlliste nicht aggregierten Spalten nicht in den GROUP BY-Klausel verweisen. ... Sie können diese Funktion verwenden, um eine bessere Leistung zu erzielen, indem unnötige Spaltensortierung und Gruppierung vermieden werden. Dies ist jedoch in erster Linie nützlich, wenn alle Werte in jeder nichtaggregierten Spalte, die nicht in GROUP BY benannt sind, für jede Gruppe gleich sind. Der Server kann aus jeder Gruppe einen beliebigen Wert auswählen. Wenn sie nicht identisch sind, sind die ausgewählten Werte unbestimmt. Außerdem kann die Auswahl von Werten aus jeder Gruppe nicht durch Hinzufügen einer ORDER BY-Klausel beeinflusst werden. Die Sortierung der Ergebnismenge erfolgt nach der Auswahl der Werte, und ORDER BY beeinflusst nicht, welche Werte der Server auswählt.

Um sicherzustellen, dass Sie die richtigen Werte zurückgeben, sollten Sie eine Unterabfrage ähnlich wie oben verwenden.

+0

Danke für die Zeit, die Sie zur Antwort genommen haben. Auf diese Weise funktioniert es wirklich so, wie ich es wollte, aber es braucht mehr Zeit als die Art, wie ich es erkläre, leider. Als Antwort markiert. – Sagevalle

+0

@Sagevalle Haben Sie Indizes für Ihre Tabellen? – Taryn

+0

Ja, in ** Table1 **'carid' und'user' und in ** Table2 **'carid'. – Sagevalle

0

Ich denke, die folgende Abfrage sollte für Ihr Szenario funktionieren. Ich habe das nicht gleich versucht, da ich die Daten nicht habe.

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

Lassen Sie mich wissen, ob das funktioniert.

+0

Es hat nicht funktioniert. – Sagevalle

Verwandte Themen