Gegeben sei folgende Tabelle:
[highlight=sql]
create table doppeltest (
id integer(8) not null auto_increment,
name varchar(64) not null,
last_use datetime not null,
constraint primary key (id)
);
[/highlight]
mit folgenden Daten:
[highlight=sql]
insert into doppeltest (name, last_use) values
('Otto', '2010-07-01 20:30:24'),
('Kurt', '2010-07-01 21:42:54'),
('Karl', '2010-07-01 18:21:31'),
('Otto', '2010-07-01 19:24:29'),
('Kurt', '2010-07-01 10:33:22'),
('Max', '2010-07-01 09:36:54'),
('Otto', '2010-07-01 21:40:27');
[/highlight]
Es sollen alle Datensätze mit "id", "name" und "last_use" aufgelistet werden, jedoch für jeden "name" nur der mit dem jüngsten "last_use". Da ausdrücklich auch eine Auflistung von "id" gefordert ist, scheidet eine einfache Gruppierung und Verwendung der Aggregatfunktion MAX() für "last_use" aus.
Die Lösung liegt in der Abfrage mittels Subselect. Jedes "last_use" wird dabei mit dem jüngsten "date" jeder mittels "name" gebildeten Gruppe verglichen.
[highlight=sql]
select a.id, a.name, a.last_use
from doppeltest a
where a.last_use = (
select max(b.last_use)
from doppeltest b
where b.name = a.name
)
[/highlight]
Ergebnis:
id name last_use 2 Kurt 2010-07-01 21:42:54 3 Karl 2010-07-01 18:21:31 6 Max 2010-07-01 09:36:54 7 Otto 2010-07-01 21:40:27
[highlight=sql]
insert into doppeltest (name, last_use) values
('Max', '2010-07-01 09:36:54');
[/highlight]
Die o.g. Lösung liefert uns jetzt wieder doppelte Werte für "name".
id name last_use 2 Kurt 2010-07-01 21:42:54 3 Karl 2010-07-01 18:21:31 6 Max 2010-07-01 09:36:54 7 Otto 2010-07-01 21:40:27 8 Max 2010-07-01 09:36:54
[highlight=sql]
select max(a.id) id, a.name, last_use
from doppeltest a
where a.last_use = (
select max(b.last_use)
from doppeltest b
where b.name = a.name
)
group by a.name, last_use
[/highlight]
Ergebnis:
id name last_use 3 Karl 2010-07-01 18:21:31 2 Kurt 2010-07-01 21:42:54 8 Max 2010-07-01 09:36:54 7 Otto 2010-07-01 21:40:27
Gruß Falk
Comment