1305 Stimmen

Abrufen des letzten Datensatzes in jeder Gruppe - MySQL

Es gibt eine Tabelle messages die Daten wie unten dargestellt enthält:

Id   Name   Other_Columns
-------------------------
1    A       A_data_1
2    A       A_data_2
3    A       A_data_3
4    B       B_data_1
5    B       B_data_2
6    C       C_data_1

Wenn ich eine Abfrage ausführe select * from messages group by name erhalte ich das folgende Ergebnis:

1    A       A_data_1
4    B       B_data_1
6    C       C_data_1

Welche Abfrage liefert das folgende Ergebnis?

3    A       A_data_3
5    B       B_data_2
6    C       C_data_1

Das heißt, der letzte Datensatz in jeder Gruppe sollte zurückgegeben werden.

Zurzeit verwende ich diese Abfrage:

SELECT
  *
FROM (SELECT
  *
FROM messages
ORDER BY id DESC) AS x
GROUP BY name

Dies erscheint jedoch äußerst ineffizient. Gibt es andere Möglichkeiten, um das gleiche Ergebnis zu erzielen?

4 Stimmen

Siehe akzeptierte Antwort in stackoverflow.com/questions/1379565/ für eine effizientere Lösung

2 Stimmen

12 Stimmen

Warum können Sie nicht einfach DESC hinzufügen, d. h. select * from messages group by name DESC

1voto

Ka. Punkte 1158

Ein anderer Ansatz:

Finden Sie das Grundstück mit dem höchsten m2_Preis in jedem Programm (n Grundstücke in 1 Programm):

select * from properties p
join (
    select max(m2_price) as max_price 
    from properties 
    group by program_id
) p2 on (p.program_id = p2.program_id)
having p.m2_price = max_price

1voto

kiruba Punkte 73

Hoffe unten Oracle Abfrage kann helfen:

WITH Temp_table AS
(
    Select id, name, othercolumns, ROW_NUMBER() over (PARTITION BY name ORDER BY ID 
    desc)as rank from messages
)
Select id, name,othercolumns from Temp_table where rank=1

1voto

Jacek Błocki Punkte 389

Worüber?

select *, max(id) from messages group by name 

Ich habe es auf Sqlite getestet und es gibt alle Spalten und max id Wert für alle Namen.

4 Stimmen

Erstens liefert Ihre Antwort im Allgemeinen kein korrektes Ergebnis für MySQL, da die maximale ID und der Rest der Spalten aus verschiedenen Datensätzen derselben Gruppe stammen könnten. Zweitens ist die gleiche Antwort bereits vorhanden ( stackoverflow.com/a/9956875/1089242 ) wie vor 9 Jahren. Drittens: In der Frage wurde speziell MySQL erwähnt. Wenn es Ihnen um allgemeine SQL-Datenbanken geht (oder nur um Sqlite), sehen Sie bitte in anderen Fragen nach, z.B. stackoverflow.com/q/3800551/1089242

1 Stimmen

Ich habe es nur mit Sqlite getestet und das Ergebnis war korrekt. MySQL habe ich nicht ausprobiert. Die Lösung war einfach, deshalb habe ich sie hier gepostet. Manchmal ist einfach falsch. Können Sie ein nicht funktionierendes sqlite-Beispiel nennen?

2 Stimmen

@JacekBocki Diese Frage bezieht sich auf MySQL. Ihre Antwort mag in Sqlite funktionieren (ich weiß es nicht, ich habe es nicht), aber sie funktioniert nicht in MySQL.

1voto

id'7238 Punkte 2298

Ab MySQL 8.0.14 kann dies auch mit Seitlich abgeleitete Tabellen :

SELECT t.*
FROM messages t
JOIN LATERAL (
  SELECT name, MAX(id) AS id 
  FROM messages t1
  WHERE t.name = t1.name
  GROUP BY name
) trn ON t.name = trn.name AND t.id = trn.id

db<>Gefiedel

1voto

ihatzi Punkte 27

Hier ist eine effizientere Version in 1 Zeile, die funktioniert, solange die Tabelle eine Zeitstempelspalte hat.

SELECT Id, Name, SUBSTRING_INDEX(MAX(CONCAT(TimeStamp, ',', Other_Columns)), ',', -1)
FROM Messages
ORDER BY id DESC GROUP BY Name 

Dies gibt den letzten Datensatz für die Gruppe in "Andere_Spalten" zurück.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X