2012-04-05 18 views
24

Meine Tabelle sieht wie folgt aus (und ich bin mit MySQL):Mit ORDER BY und GROUP BY zusammen

m_id | v_id | timestamp 
------------------------ 
6 | 1 | 1333635317 
34 | 1 | 1333635323 
34 | 1 | 1333635336 
6 | 1 | 1333635343 
6 | 1 | 1333635349 

Mein Ziel ist durch den höchsten Zeitstempel jedes m_id einmal, und zu ergreifen.

m_id | v_id | timestamp 
------------------------ 
6 | 1 | 1333635343 
34 | 1 | 1333635336 

Und ich schrieb diese Abfrage:

sollte das Ergebnis sein

SELECT * FROM table GROUP BY m_id ORDER BY timestamp DESC 

Aber sind die Ergebnisse:

m_id | v_id | timestamp 
------------------------ 
34 | 1 | 1333635323 
6 | 1 | 1333635317 

ich denke, es verursacht, weil es zuerst tut GROUP_BY und dann BESTELLEN Sie die Ergebnisse.

Irgendwelche Ideen? Vielen Dank.

+2

Verwendung 'MAX' die max aus Ihrer Gruppe – Nanne

+6

A' GROUP BY'-Klausel ohne Aggregat-Funktion zu wählen (zB: COUNT(), SUM(), MAX() ') überhaupt keinen Sinn macht . Es verblüfft mich, dass MySQL dies sogar erlaubt. Denk darüber nach, warum gruppierst du dich, wenn du nichts mit den Gruppen machst? – NullUserException

+0

Was passiert, wenn es zwei verschiedene v_id für eine m_id gibt? Was wäre das gewünschte Ergebnis? –

Antwort

31

Eine Möglichkeit, dies zu tun, richtig verwendet group by:

select l.* 
from table l 
inner join (
    select 
    m_id, max(timestamp) as latest 
    from table 
    group by m_id 
) r 
    on l.timestamp = r.latest and l.m_id = r.m_id 
order by timestamp desc 

Wie das funktioniert:

  • die neuesten Zeitstempel für jede einzelne m_id in der Unterabfrage nur
  • Zeilen auswählt aus table wählt das entspricht einer Zeile aus der Unterabfrage (diese Operation - wo eine Verknüpfung ausgeführt wird, aber keine Spalten aus der zweiten Tabelle ausgewählt sind, sondern nur als Filter verwendet wird - ist bekannt n als "semijoin" im Fall waren Sie neugierig)
  • die Zeilen bestellt
+0

Vielen Dank, es funktioniert super. Kannst du mir erklären, was ist das "r"? es ist eine temporäre Tabelle? Wie ruft es in SQL auf? – Luis

+1

@luis - Stellen Sie sich vor, dass die Unterabfrage eine Ansicht ist; eine Inline-Ansicht. Es braucht einen Namen, damit Sie es und seine Felder referenzieren können. Diese Antwort gibt der Inline-Ansicht den Namen "r". Du könntest es fast alles nennen was du willst. – MatBailie

+2

@Luis ist ein Alias, mit dem Sie auf die Unterabfrage verweisen können. Ich hätte auch '(select ...) als r 'schreiben können (notiere das as), um es klarer zu machen. –

5

Wenn Sie wirklich, über die nicht kümmern zeitzustempeln Sie erhalten und Ihre v_id ist immer das gleiche für eine gegebene m_i Sie tun können die folgenden:

select m_id, v_id, max(timestamp) from table 
group by m_id, v_id 
order by timestamp desc 

wenn nun die v_id Änderungen für einen bestimmten m_id dann sollten Sie die folgenden

select t1.* from table t1 
left join table t2 on t1.m_id = t2.m_id and t1.timestamp < t2.timestamp 
where t2.timestamp is null 
order by t1.timestamp desc 
tun
2

SQL>

SELECT interview.qtrcode QTR, interview.companyname "Company Name", interview.division Division 
FROM interview 
JOIN jobsdev.employer 
    ON (interview.companyname = employer.companyname AND employer.zipcode like '100%') 
GROUP BY interview.qtrcode, interview.companyname, interview.division 
ORDER BY interview.qtrcode; 
3

können Sie versuchen, diese

SELECT tbl.* FROM (SELECT * FROM table ORDER BY timestamp DESC) as tbl 
GROUP BY tbl.m_id 
+0

Keine gute Idee. Sie wählen alle Zeilen ohne Einschränkung – AliN11

1

Nur du mit asc desc müssen. Schreiben Sie die Abfrage wie folgt. Es wird die Werte in aufsteigender Reihenfolge zurückgeben. SELECT * FROM Tabelle GROUP BY m_id ORDER BY m_id asc;

+0

Das wird nicht funktionieren. Während es die Ergebnisse umkehrt, wird es immer noch nicht die gewünschten Ergebnisse liefern. – Richlv

0

Sie müssen DESC durch ASC ersetzen. Schreiben Sie die Abfrage wie folgt und die Werte werden in aufsteigender Reihenfolge zurückgegeben.

SELECT * FROM table GROUP BY m_id ORDER BY m_id ASC;