Hallo Martin,
Ich denke viele klicken das Thema gar nicht erst an, da es schon so oft vorkam.
die Lösung zu Deinem Problem ist es, sich von GROUP BY zu lösen.
Du suchst eine korrelierte Unterabfrage. Schauen wir es uns an Deinem Beispiel an:
Tabelle stream:
stream_id user_id type_id linux_timestamp
----------- ----------- ----------- ---------------
1 230 2 1268615468
2 180 2 1268615483
3 230 1 1268615504
4 230 3 1268615555
5 320 1 1268615567
Tabelle benutzer
user_id nickname vorname vornameview
----------- ---------- ---------- -----------
180 martin Martin 1
230 theo Theodor 1
320 jonas Jonas 1
Tabelle type (mit leicht modifizierten Inhalten)
type_id type_text icon
----------- ---------- ----------
1 Text 1 Icon 1
2 Text 2 Icon 2
3 Text 3 Icon 3
Du suchst zunächst die zwei neuesten Einträge in stream unter der Randbedingung, dass sie von unterschiedlichen Benutzern stammen. Die user_id und den zugehörigen linux_timestamp könntest Du zwar über GROUP BY mit Hilfe der Aggregatsfunktion MAX() bestimmen, nicht jedoch den zugehörigen Eintrag in der Spalte type_id. Dazu benötigst Du - wie bereits erwähnt - eine korrelierte Unterabfrage:
Wir beschaffen uns im ersten Schritt die neuesten Einträge *aller* Benutzer und sortieren die Ergebnismenge absteigend nach dem Eintragszeitpunkt, um die neuesten als erste zu erhalten:
SELECT -- Gib mir die Inhalte der Spalten
s1.stream_id, -- stream_id
s1.user_id, -- user_id
s1.type_id, -- type_id
s1.linux_timestamp, -- und Timestamp
FROM -- aus
stream s1 -- der Tabelle stream, die unter dem
-- Namen s1 angesprochen wird.
-- Der Aliasname ist notwendig, weil wir
-- im Subselect auf die gleiche Tabelle
-- zugreifen, um äußeren von innerem Zugriff
-- unterscheiden zu können
WHERE -- wobei uns nur die Datensätze interessieren,
s1.linux_timestamp = ( -- deren Timestamp mit
SELECT -- dem
MAX(s2.linux_timestamp) -- maximalen Timestamp
FROM -- aus der Tabellle
stream s2 -- stream, hier zur Unterscheidung über
-- den Alias s2 angesprochen,
-- übereinstimmt
WHERE -- wobei nur die Datensätze interessieren,
s1.user_id = s2.user_id -- bei denen die user_id innen und außen
-- gleich ist.
-- Das ist die Korrelation des Subselects
-- mit der äußeren Abfrage.
)
ORDER BY -- Ergebnisse bitte
s1.linux_timestamp DESC -- nach Timestamp-Spalte absteigend sortiert
Ergebnis:
stream_id user_id type_id linux_timestamp
----------- ----------- ----------- ---------------
5 320 1 1268615567
4 230 3 1268615555
2 180 2 1268615483
Im zweiten Schritt besorgen wir uns über entsprechende Joins die Daten aus den anderen Tabellen und limitieren die Ergebnismenge auf zwei Datensätze:
SELECT
s1.stream_id,
s1.user_id,
s1.type_id,
s1.linux_timestamp,
b.nickname,
b.vorname,
b.vornameview,
t.type_text,
t.icon
FROM
stream s1
INNER JOIN -- ganz normale INNER JOINs
benutzer b
ON
s1.user_id = b.user_id
INNER JOIN
`type` t --
ON
s1.type_id = t.type_id
WHERE
s1.linux_timestamp = (
SELECT
MAX(s2.linux_timestamp)
FROM
stream s2
WHERE
s1.user_id = s2.user_id
)
ORDER BY
s1.linux_timestamp DESC
LIMIT 2 -- limitiere die Ergebnismenge
Ergebnis (wie gewünscht):
stream_id user_id type_id linux_timestamp nickname vorname vornameview type_text icon
----------- ----------- ----------- --------------- ---------- ---------- ----------- ---------- ----------
5 320 1 1268615567 jonas Jonas 1 Text 1 Icon 1
4 230 3 1268615555 theo Theodor 1 Text 3 Icon 3
Freundliche Grüße
Vinzenz