wake-up-neo.com

ORDER BY Datum und Uhrzeit VOR GROUP BY Name in MySQL

ich habe einen Tisch wie diesen:

name    date         time
tom | 2011-07-04 | 01:09:52
tom | 2011-07-04 | 01:09:52
mad | 2011-07-04 | 02:10:53
mad | 2009-06-03 | 00:01:01

ich möchte zuerst den ältesten Namen: 

SELECT * 
ORDER BY date ASC, time ASC 
GROUP BY name

(-> geht nicht!)

jetzt sollte es mir zuerst wahnsinnig geben (hat früheres datum) dann tom

aber mit GROUP BY name ORDER BY date ASC, time ASC gibt mir der neuere verrückte zuerst, weil er gruppiert, bevor er sortiert!

nochmal: das problem ist, dass ich nicht nach datum und uhrzeit sortieren kann, bevor ich gruppiere, da GROUP BY vor ORDER BY sein muss!

48
CodingYourLife

Eine andere Methode:

SELECT * 
FROM (
    SELECT * 
    ORDER BY date ASC, time ASC 
) AS sub
GROUP BY name

GROUP BY gruppiert das erste übereinstimmende Ergebnis, das es trifft. Wenn der erste Treffer genau der Treffer ist, den Sie möchten, sollte alles wie erwartet funktionieren.

Ich bevorzuge diese Methode, da die Unterabfrage logisch sinnvoll ist, anstatt sie mit anderen Bedingungen zu überlisten.

69
user1908688

Ich denke, das ist es, was Sie suchen:

SELECT name, min(date)
FROM myTable
GROUP BY name
ORDER BY min(date)

Für die Zeit müssen Sie ein Mysql-Datum über STR_TO_DATE machen:

STR_TO_DATE(date + ' ' + time, '%Y-%m-%d %h:%i:%s')

So :

SELECT name, min(STR_TO_DATE(date + ' ' + time, '%Y-%m-%d %h:%i:%s'))
FROM myTable
GROUP BY name
ORDER BY min(STR_TO_DATE(date + ' ' + time, '%Y-%m-%d %h:%i:%s'))
25
Cyril Gandon

Da ich die Antwort von user1908688 nicht kommentieren darf, hier ein Hinweis für MariaDB-Benutzer:

SELECT *
FROM (
     SELECT *
     ORDER BY date ASC, time ASC
     LIMIT 18446744073709551615
     ) AS sub
GROUP BY sub.name

https://mariadb.com/kb/de/mariadb/why-isorder-by-in-a-from-subquery-ignored/

20
Vincent

Das hat für mich funktioniert:

SELECT *
FROM your_table
WHERE id IN (
    SELECT MAX(id)
    FROM your_table
    GROUP BY name
);
8
jokermt235

Verwenden Sie eine Unterauswahl:

select name, date, time
from mytable main
where date + time = (select min(date + time) from mytable where name = main.mytable)
order by date + time;
3
Bohemian

Ich hatte eine andere Variante für diese Frage, bei der ich nur ein einziges DATETIME-Feld hatte und einen limit nach einem group by oder distinct brauchte, nachdem ich nach dem datetime-Feld absteigend sortiert hatte.

select distinct (column) from
(select column from database.table
order by date_column DESC) as hist limit 10

Wenn Sie in diesem Fall mit den aufgeteilten Feldern nach einem Concat sortieren können, können Sie möglicherweise Folgendes mitbekommen:

select name,date,time from
(select name from table order by concat(date,' ',time) ASC)
as sorted

Wenn Sie das Limit begrenzen möchten, fügen Sie einfach Ihre Limit-Anweisung am Ende hinzu:

select name,date,time from
(select name from table order by concat(date,' ',time) ASC)
as sorted limit 10
0
AbsoluteƵERØ

Eine andere Möglichkeit, dies zu lösen, wäre ein LEFT JOIN, der effizienter sein könnte. Ich beginne zunächst mit einem Beispiel, das nur das Datumsfeld berücksichtigt. Wahrscheinlich ist es üblicher, Datum + Uhrzeit in einer Datetime-Spalte zu speichern. Außerdem möchte ich die Abfrage einfach halten, um sie verständlicher zu machen.

Wenn Sie also in diesem speziellen Beispiel den Datensatz älteste basierend auf der Spalte date anzeigen möchten und davon ausgehen, dass Ihr Tabellenname people lautet, können Sie die folgende Abfrage verwenden:

SELECT p.* FROM people p
LEFT JOIN people p2 ON p.name = p2.name AND p.date > p2.date
WHERE p2.date is NULL
GROUP BY p.name

Was der LEFT JOIN tut, ist, wenn die p.date-Spalte ihren Minimalwert hat, kein p2.date mit einem kleineren Wert im linken Join vorhanden ist, und daher ist der entsprechende p2.dateNULL. Indem Sie WHERE p2.date is NULL hinzufügen, stellen Sie sicher, dass nur die Datensätze mit dem ältesten Datum angezeigt werden.

Wenn Sie stattdessen den neuesten -Datensatz anzeigen möchten, können Sie einfach den Vergleichsoperator im LEFT JOIN ändern:

SELECT p.* FROM people p
LEFT JOIN people p2 ON p.name = p2.name AND p.date < p2.date
WHERE p2.date is NULL
GROUP BY p.name

Für dieses spezielle Beispiel, bei dem Datum + Uhrzeit separate Spalten sind, müssen Sie diese auf irgendeine Weise hinzufügen, wenn Sie die Abfrage basierend auf der Datumszeit von zwei kombinierten Spalten abfragen möchten. Beispiel:

SELECT p.* FROM people p
LEFT JOIN people p2 ON p.name = p2.name AND p.date + INTERVAL TIME_TO_SEC(p.time) SECOND > p2.date + INTERVAL TIME_TO_SEC(p2.time) SECOND
WHERE p2.date is NULL
GROUP BY p.name

Weitere Informationen hierzu finden Sie auf der Zeilen, die das gruppenweise Maximum einer bestimmten Spalte enthalten.

0
Ben