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

6voto

Jeet Singh Parmar Punkte 667
SELECT 
  column1,
  column2 
FROM
  table_name 
WHERE id IN 
  (SELECT 
    MAX(id) 
  FROM
    table_name 
  GROUP BY column1) 
ORDER BY column1 ;

1 Stimmen

Könnten Sie Ihre Antwort etwas näher erläutern? Warum ist Ihre Anfrage der ursprünglichen Anfrage von Vijay vorzuziehen?

6voto

Shrikant Gupta Punkte 121

Sie können auch von hier aus die Aussicht genießen.

http://sqlfiddle.com/#!9/ef42b/9

ERSTE LÖSUNG

SELECT d1.ID,Name,City FROM Demo_User d1
INNER JOIN
(SELECT MAX(ID) AS ID FROM Demo_User GROUP By NAME) AS P ON (d1.ID=P.ID);

ZWEITE LÖSUNG

SELECT * FROM (SELECT * FROM Demo_User ORDER BY ID DESC) AS T GROUP BY NAME ;

6voto

Wenn Sie den jüngsten oder ältesten Datensatz einer Textspalte in einer gruppierten Abfrage benötigen und keine Unterabfrage verwenden möchten, können Sie Folgendes tun...

Ex. Sie haben eine Liste von Filmen und müssen die Anzahl der Filme in der Serie und den neuesten Film ermitteln

id

Serie

Name

1

Krieg der Sterne

Eine neue Hoffnung

2

Krieg der Sterne

Das Imperium schlägt zurück

3

Krieg der Sterne

Die Rückkehr der Jedi

SELECT COUNT(id), series, SUBSTRING(MAX(CONCAT(id, name)), LENGTH(id) + 1), 
FROM Movies
GROUP BY series

Das bringt...

id

Serie

Name

3

Krieg der Sterne

Die Rückkehr der Jedi

MAX gibt die Zeile mit dem höchsten Wert zurück. Wenn Sie also die ID mit dem Namen verknüpfen, erhalten Sie den neuesten Datensatz und können die ID für das Endergebnis einfach entfernen.

Effizienter als die Verwendung einer Unterabfrage.

Also für das gegebene Beispiel:

SELECT MAX(Id), Name, SUBSTRING(MAX(CONCAT(Id, Other_Columns)), LENGTH(Id) + 1), 
FROM messages
GROUP BY Name

Fröhliche Codierung und "Möge die Macht mit dir sein" :)

0 Stimmen

Das funktioniert möglicherweise nicht. Nehmen wir an, dass in Ihrem Beispiel die ID von "A New Hope" 9 und die ID von "Return of The Jedi" 10 ist. Das liegt daran, dass die MAX-Funktion für die Verkettung von id und name eine Zeichenkette verarbeiten würde. Somit hätte "9A New hope" eine höhere Ordnung als "10Return of The Jedi".

5voto

Ich habe noch nicht mit großen DB getestet, aber ich denke, dies könnte schneller sein als das Verbinden von Tabellen:

SELECT *, Max(Id) FROM messages GROUP BY Name

20 Stimmen

Dies gibt beliebige Daten zurück. Mit anderen Worten: Die zurückgegebenen Spalten stammen möglicherweise nicht aus dem Datensatz mit MAX(Id).

0 Stimmen

Nützlich für die Auswahl der maximalen Id aus einem Satz von Datensätzen mit WHERE-Bedingung: "SELECT Max(Id) FROM Prod WHERE Pn='" + Pn + "". + Pn + "'" Es gibt die maximale Id aus einer Reihe von Datensätzen mit demselben Pn zurück. In c# verwenden Sie reader.GetString(0), um das Ergebnis zu erhalten.

0 Stimmen

Warum hat dieser Beitrag überhaupt positive Stimmen erhalten? Meiner Meinung nach geht er völlig am Thema vorbei.

5voto

Abhishek Sengupta Punkte 2136

**

Hallo, diese Anfrage könnte hilfreich sein:

**

SELECT 
  *
FROM 
  message 

WHERE 
  `Id` IN (
    SELECT 
      MAX(`Id`) 
    FROM 
      message 
    GROUP BY 
      `Name`
  ) 
ORDER BY 
   `Id` DESC

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