Mein Tisch ist:
id home datetime player resource
---|-----|------------|--------|---------
1 | 10 | 04/03/2009 | john | 399
2 | 11 | 04/03/2009 | juliet | 244
5 | 12 | 04/03/2009 | borat | 555
3 | 10 | 03/03/2009 | john | 300
4 | 11 | 03/03/2009 | juliet | 200
6 | 12 | 03/03/2009 | borat | 500
7 | 13 | 24/12/2008 | borat | 600
8 | 13 | 01/01/2009 | borat | 700
Ich muss jedes einzelne auswählen home
, das den Maximalwert von enthält datetime
.
Ergebnis wäre:
id home datetime player resource
---|-----|------------|--------|---------
1 | 10 | 04/03/2009 | john | 399
2 | 11 | 04/03/2009 | juliet | 244
5 | 12 | 04/03/2009 | borat | 555
8 | 13 | 01/01/2009 | borat | 700
Ich habe versucht:
-- 1 ..by the MySQL manual:
SELECT DISTINCT
home,
id,
datetime AS dt,
player,
resource
FROM topten t1
WHERE datetime = (SELECT
MAX(t2.datetime)
FROM topten t2
GROUP BY home)
GROUP BY datetime
ORDER BY datetime DESC
Funktioniert nicht Die Ergebnismenge enthält 130 Zeilen, obwohl die Datenbank 187 enthält home
. Das Ergebnis enthält einige Duplikate von .
-- 2 ..join
SELECT
s1.id,
s1.home,
s1.datetime,
s1.player,
s1.resource
FROM topten s1
JOIN (SELECT
id,
MAX(datetime) AS dt
FROM topten
GROUP BY id) AS s2
ON s1.id = s2.id
ORDER BY datetime
Nee. Gibt alle Aufzeichnungen.
-- 3 ..something exotic:
Mit verschiedenen Ergebnissen.
id
,player
undresource
von nicht-max Zeile für ein Haus für Haus dh gegeben 10 = Sie bekommen können:3 | 10 | 04/03/2009 | john | 300
Mit anderen Worten ist es garantiert nicht , dass alle Spalte einer Zeile in resultset gehören wird bis max (datetime) für gegebenes Zuhause.Die schnellste
MySQL
Lösung, ohne innere Fragen und ohneGROUP BY
:Erklärung :
Verbinden Sie die Tabelle mit sich selbst mithilfe der
home
Spalte. Durch die Verwendung von wirdLEFT JOIN
sichergestellt, dass alle Zeilen aus der Tabellem
in der Ergebnismenge angezeigt werden. Diejenigen, die keine Übereinstimmung in der Tabelleb
haben, habenNULL
s für die Spalten vonb
.Die andere Bedingung in der
JOIN
Aufforderung, nur den Zeilen zuzuordnenb
, die einen größeren Wert in derdatetime
Spalte haben als die Zeile ausm
.Unter Verwendung der in der Frage angegebenen Daten
LEFT JOIN
werden die folgenden Paare erzeugt:Schließlich enthält die
WHERE
Klausel nur die Paare, dieNULL
s in den Spalten von habenb
(sie sind*
in der obigen Tabelle mit gekennzeichnet ). Dies bedeutet, dass aufgrund der zweiten Bedingung aus derJOIN
Klausel die ausgewählte Zeilem
den größten Wert in der Spalte hatdatetime
.Lesen Sie die SQL - Antipatterns: Die Vermeidung der Gefahren von Datenbankprogrammierung Buch für andere SQL - Tipps.
quelle
SQLite
ist die erste viel langsamer als die Version von La Voie, wenn es keinen Index für die übereinstimmende Spalte gibt (dh "home"). (Getestet mit 24k Reihen, was 13k Reihen ergibt)home
unddatetime
und dasdatetime
ist das Maximum für diesen bestimmthome
?ON
Klausel ein. Fe... ON ... AND m.id < b.id
, um den neuesten Eintrag (den mit dem größtenid
) beizubehalten, wenn zwei Zeilen dieselben Werte inhome
unddatetime
Spalten haben und dies das Maximum istdatetime
.Hier geht T-SQL- Version:
BEARBEITEN
Leider gibt es in MySQL keine RANK () OVER-Funktion.
Es kann jedoch emuliert werden, siehe Emulieren von Analysefunktionen (AKA-Ranking) mit MySQL .
Das ist also die MySQL- Version:
quelle
Dies funktioniert auch dann, wenn Sie zwei oder mehr Zeilen mit jeweils
home
gleichen Zeilen habenDATETIME
:quelle
WHERE ti.home = t1.home
- Können Sie die Syntax erklären?select
Abfrage mit der ZeileWHERE ti.home = t1.home
benötigt nicht dieFROM
definierte Klauselt1
. Wie wird es verwendet?Ich denke, dies wird Ihnen das gewünschte Ergebnis bringen:
ABER wenn Sie auch andere Spalten benötigen, stellen Sie einfach eine Verknüpfung mit der Originaltabelle her (
Michael La Voie
Antwort überprüfen )Freundliche Grüße.
quelle
Da die Leute immer wieder auf diesen Thread stoßen (das Kommentardatum liegt zwischen 1,5 Jahren), ist das nicht viel einfacher:
SELECT * FROM (SELECT * FROM topten ORDER BY datetime DESC) tmp GROUP BY home
Keine Aggregationsfunktionen erforderlich ...
Prost.
quelle
Sie können dies auch versuchen und bei großen Tabellen ist die Abfrageleistung besser. Es funktioniert, wenn nicht mehr als zwei Datensätze für jedes Haus vorhanden sind und die Daten unterschiedlich sind. Eine bessere allgemeine MySQL-Abfrage stammt von Michael La Voie oben.
Oder versuchen Sie es bei Postgres oder solchen Datenbankanbietern, die Analysefunktionen bereitstellen
quelle
SQLite
ist die erste viel langsamer als die Version von La Voie, wenn es keinen Index für die übereinstimmende Spalte gibt (dh "home").Dies funktioniert unter Oracle:
quelle
quelle
Versuchen Sie dies für SQL Server:
quelle
quelle
Hier ist die MySQL-Version, die nur einen Eintrag druckt, in dem Duplikate MAX (datetime) in einer Gruppe vorhanden sind.
Sie können hier http://www.sqlfiddle.com/#!2/0a4ae/1 testen
Beispieldaten
MySQL-Version mit Benutzervariable
Akzeptierte Antworten
quelle
Eine andere Möglichkeit, die letzte Zeile pro Gruppe mithilfe einer Unterabfrage zu ermitteln, die im Grunde genommen einen Rang für jede Zeile pro Gruppe berechnet und dann Ihre neuesten Zeilen wie mit Rang = 1 herausfiltert
DEMO
Hier ist die visuelle Demo für Rang Nr. Für jede Zeile zum besseren Verständnis
Die obige Abfrage schlägt fehl und gibt für die obige Situation mehr als 1 Zeilen zurück. Um diese Situation zu vertuschen, müssen andere Kriterien / Parameter / Spalten verwendet werden, um zu entscheiden, welche Zeile in die obige Situation fallen soll. Beim Anzeigen des Beispieldatensatzes gehe ich davon aus, dass es eine Primärschlüsselspalte gibt
id
, die auf automatische Inkrementierung eingestellt werden sollte. Wir können diese Spalte also verwenden, um die neueste Zeile auszuwählen, indem wir dieselbe Abfrage mit Hilfe einerCASE
Anweisung wie optimierenDEMO
Die obige Abfrage wählt die Zeile mit der höchsten ID unter denselben
datetime
Werten ausvisuelle Demo für Rang Nr. für jede Zeile
quelle
Warum nicht verwenden: SELECT home, MAX (datetime) AS MaxDateTime, Player, Ressource FROM topten GROUP BY home Habe ich etwas verpasst?
quelle
expected
Ausgabe in MySQL Version 5.6 nicht zurückbefore
und ich bezweifle sehr, dass sie sich in MySQL Version 5.7 und anders verhältafter
.Versuche dies
Grüße K.
quelle
max(datetime)
istdatetime
. Wird es kein Problem machen?datetime
ausgewählt?Dies ist die Abfrage, die Sie benötigen:
quelle
@Michae Die akzeptierte Antwort funktioniert in den meisten Fällen einwandfrei, schlägt jedoch für eine der folgenden fehl.
Falls zwei Zeilen mit der gleichen HomeID und Datetime vorhanden sind, gibt die Abfrage beide Zeilen zurück, nicht die erforderliche HomeID, um Distinct in der Abfrage wie folgt hinzuzufügen.
quelle
Hoffe, dass die folgende Abfrage die gewünschte Ausgabe liefert:
quelle