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

4voto

ShriP Punkte 119
SELECT * FROM table_name WHERE primary_key IN (SELECT MAX(primary_key) FROM table_name GROUP BY column_name )

4voto

milad Punkte 121

Ich finde die beste Lösung in https://dzone.com/articles/get-last-record-in-each-mysql-group

select * from `data` where `id` in (select max(`id`) from `data` group by `name_id`)

6 Stimmen

Haben Sie diese Frage nicht in den Antworten gesehen, die bereits veröffentlicht wurden?

4voto

Abhishek Yadav Punkte 89

Hier ist meine Lösung:

SELECT 
  DISTINCT NAME,
  MAX(MESSAGES) OVER(PARTITION BY NAME) MESSAGES 
FROM MESSAGE;

1 Stimmen

Es wird nicht die letzte Nachricht pro Name zurückgegeben. Und es ist nur eine überkomplizierte Version von SELECT NAME, MAX(MESSAGES) MESSAGES FROM MESSAGE GROUP BY NAME .

0 Stimmen

Außerdem ist diese Formulierung äußerst ineffizient.

4voto

Pro Web Design Punkte 31

Versuchen Sie dies:

SELECT jos_categories.title AS name,
       joined .catid,
       joined .title,
       joined .introtext
FROM   jos_categories
       INNER JOIN (SELECT *
                   FROM   (SELECT `title`,
                                  catid,
                                  `created`,
                                  introtext
                           FROM   `jos_content`
                           WHERE  `sectionid` = 6
                           ORDER  BY `id` DESC) AS yes
                   GROUP  BY `yes`.`catid` DESC
                   ORDER  BY `yes`.`created` DESC) AS joined
         ON( joined.catid = jos_categories.id )

4voto

Simon Punkte 8817

Gibt es eine Möglichkeit, diese Methode zum Löschen von Duplikaten in einer Tabelle zu verwenden? Die Ergebnismenge ist im Grunde eine Sammlung eindeutiger Datensätze. Wenn wir also alle Datensätze löschen könnten, die nicht in der Ergebnismenge enthalten sind, hätten wir effektiv keine Duplikate? Ich habe dies versucht, aber mySQL gab einen 1093-Fehler aus.

DELETE FROM messages WHERE id NOT IN
 (SELECT m1.id  
 FROM messages m1 LEFT JOIN messages m2  
 ON (m1.name = m2.name AND m1.id < m2.id)  
 WHERE m2.id IS NULL)

Gibt es eine Möglichkeit, die Ausgabe vielleicht in einer temporären Variable zu speichern und dann aus NOT IN (temporäre Variable) zu löschen? @Bill danke für eine sehr nützliche Lösung.

EDIT: Ich glaube, ich habe die Lösung gefunden:

DROP TABLE IF EXISTS UniqueIDs; 
CREATE Temporary table UniqueIDs (id Int(11)); 

INSERT INTO UniqueIDs 
    (SELECT T1.ID FROM Table T1 LEFT JOIN Table T2 ON 
    (T1.Field1 = T2.Field1 AND T1.Field2 = T2.Field2 #Comparison Fields  
    AND T1.ID < T2.ID) 
    WHERE T2.ID IS NULL); 

DELETE FROM Table WHERE id NOT IN (SELECT ID FROM UniqueIDs);

0 Stimmen

Interessant, weil verwandt, aber ist das nicht ein eigenes Q&A wert?

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