Ich habe eine Tabelle, die eine Sammlung von Einträgen darüber enthält, wann ein Benutzer angemeldet war.
username, date, value
--------------------------
brad, 1/2/2010, 1.1
fred, 1/3/2010, 1.0
bob, 8/4/2009, 1.5
brad, 2/2/2010, 1.2
fred, 12/2/2009, 1.3
etc..
Wie erstelle ich eine Abfrage, die mir das neueste Datum für jeden Benutzer gibt?
Update: Ich habe vergessen, dass ich einen Wert haben muss, der mit dem letzten Datum übereinstimmt.
sql
greatest-n-per-group
Fischkopf
quelle
quelle
Antworten:
quelle
max(date)
würde ein Datum zurückgeben, das mehrere Datensätze verbinden würde). Um dieses Problem zu vermeiden, ist es vorzuziehen, die Lösung von @ dotjoe zu verwenden: stackoverflow.com/a/2411763/4406793 .Verwenden von Fensterfunktionen (funktioniert in Oracle, Postgres 8.4, SQL Server 2005, DB2, Sybase, Firebird 3.0, MariaDB 10.3)
quelle
username
in diesem Fall) und nicht einmal ein eindeutiges "bestellbares" Feld erforderlich ist (wie das Mitmachenmax(date)
in anderen Antworten).order by date desc, id desc)
.Ich sehe, dass die meisten Entwickler eine Inline-Abfrage verwenden, ohne die Auswirkungen auf große Datenmengen zu berücksichtigen.
Sie können dies einfach erreichen, indem Sie:
quelle
So erhalten Sie die gesamte Zeile mit dem maximalen Datum für den Benutzer:
quelle
quelle
Nach meiner Erfahrung ist der schnellste Weg, jede Zeile zu nehmen, für die es keine neuere Zeile in der Tabelle gibt.
Ein weiterer Vorteil ist, dass die verwendete Syntax sehr einfach ist und die Bedeutung der Abfrage ziemlich leicht zu verstehen ist (nehmen Sie alle Zeilen so, dass für den betrachteten Benutzernamen keine neuere Zeile vorhanden ist).
EXISTIERT NICHT
ZEILENNUMMER
INNER JOIN
LINKE ÄUSSERE VERBINDUNG
quelle
SELECT username, value FROM t WHERE NOT EXISTS ( SELECT * FROM t AS witness WHERE witness.date > t.date AND witness.username = t.username );
Dieser sollte Ihnen das richtige Ergebnis für Ihre bearbeitete Frage liefern.
Die Unterabfrage stellt sicher, dass nur Zeilen mit dem letzten Datum gefunden werden, und die äußere Abfrage
GROUP BY
kümmert sich um die Verknüpfungen. Wenn zwei Einträge für dasselbe Datum für denselben Benutzer vorhanden sind, wird der Eintrag mit dem höchsten zurückgegebenvalue
.quelle
Sie können auch die analytische Rangfunktion verwenden
quelle
Würde das aktualisierte Problem beheben. Bei großen Tabellen funktioniert dies möglicherweise nicht so gut, selbst bei guter Indizierung.
quelle
quelle
Bei Oracle sortiert die Ergebnismenge in absteigender Reihenfolge und nimmt den ersten Datensatz, sodass Sie den neuesten Datensatz erhalten:
quelle
quelle
quelle
Select * from table1 where lastest_date=(select Max(latest_date) from table1 where user=yourUserName)
Die innere Abfrage gibt das späteste Datum für den aktuellen Benutzer zurück. Die äußere Abfrage ruft alle Daten gemäß dem Ergebnis der inneren Abfrage ab.
quelle
Auf diese Weise habe ich den letzten Datensatz für jeden Benutzer erstellt, den ich auf meinem Tisch habe. Es war eine Abfrage, um den letzten Standort für den Verkäufer zu ermitteln, der zuletzt auf PDA-Geräten ermittelt wurde.
quelle
quelle
Meine kleine Zusammenstellung
join
besser als verschachteltselect
group by
gibt dir aber nichtprimary key
was für vorzuziehen istjoin
partition by
in Verbindung mitfirst_value
( docs ) angegeben werden.Also, hier ist eine Abfrage:
Vorteile:
where
Anweisungen mithilfe einer beliebigen Spalteselect
Alle Spalten aus gefilterten ZeilenNachteile:
quelle
Ich habe etwas für meine Bewerbung getan, da es:
Unten ist die Abfrage:
quelle
Dies ähnelt einer der obigen Antworten, ist aber meiner Meinung nach viel einfacher und aufgeräumter. Zeigt auch eine gute Verwendung für die Kreuzanwendungsanweisung. Für SQL Server 2005 und höher ...
quelle
quelle
Dies sollte auch funktionieren, um die neuesten Einträge für Benutzer zu erhalten.
quelle
Sie würden die Aggregatfunktion MAX und GROUP BY verwenden
quelle
value
, nicht der mit derMAX(date)
Zeile verknüpfte .