Eine immer wiederkehrende Problemstellung: In einer Tabelle sind zu verschiedenen Kategorien mehrere Einträge gespeichert (z.B. ein Forum o.ä.). Nun gilt es, zu jeder Kategorie den jeweils aktuellsten Datensatz zu ermitteln.
Wir haben beispielsweise folgende Tabelle:
CREATE TABLE `tab1` (
`id` int(11) default NULL,
`cat` int(11) default NULL,
`titel` char(100) default NULL,
`time` time default NULL
);
Die Tabelle enthält natürlich auch Daten:
+------+------+------------+----------+
| id | cat | titel | time |
+------+------+------------+----------+
| 1 | 1 | datensatz1 | 00:00:15 |
| 2 | 2 | datensatz2 | 00:01:00 |
| 3 | 3 | datensatz3 | 00:02:00 |
| 4 | 1 | datensatz4 | 00:01:00 |
| 5 | 2 | datensatz5 | 00:02:15 |
| 6 | 3 | datensatz6 | 00:01:15 |
+------+------+------------+----------+
(insert into tab1 values (1, 1, ‚datensatz1′, ’00:00:15‘), (2, 2, ‚datensatz2′, ’00:01:00‘), (3, 3, ‚datensatz3′, ’00:02:00‘), (4, 1, ‚datensatz4′, ’00:01:00‘), (5, 2, ‚datensatz5′, ’00:02:15‘), (6, 3, ‚datensatz6′, ’00:01:15‘);)
Um nun das gewünschte Ergebnis zu bekommen, benutz man eine sog. Self-Left-Join, also einen Left-Join mit der selben Tabelle:
SELECT x.* FROM tab1 AS x LEFT JOIN tab1 AS y
ON x.cat = y.cat AND x.time < y.time
WHERE y.id IS NULL ORDER BY cat;
+------+------+------------+----------+
| id | cat | titel | time |
+------+------+------------+----------+
| 4 | 1 | datensatz4 | 00:01:00 |
| 5 | 2 | datensatz5 | 00:02:15 |
| 3 | 3 | datensatz3 | 00:02:00 |
+------+------+------------+----------+
Nach einem Post von Björn Brinkhoff (bjoern-at-brinkhoff-dot-org) in der deutschen MySQL-Mailinglist mysql-de@lists.mysql.com am 13.11.2007