Mailinglisten-Archive |
Manuel Hossfeld wrote: > ich habe hier eine datenbankbasierte PHP-Anwendung, bei der unter anderem eine > Liste von Dokumenten angezeigt wird. Diese Dokumente haben ID und Version als > kombinierten primary key (d.h. es können also mehrere Versionen ein und > desselben Doks vorhanden sein). Nun will ich aber, daß per Default nur die > jeweils neueste Version jedes Doks angezeigt wird. mysql> desc doc; +-------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+-------+ | id | int(11) | | PRI | 0 | | | ver | int(11) | | PRI | 0 | | | daten | varchar(127) | | | | | +-------+--------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) mysql> select * from doc; +----+-----+--------------+ | id | ver | daten | +----+-----+--------------+ | 1 | 1 | doc 1 ver 1 | | 1 | 2 | doc 1 ver 2 | | 2 | 10 | doc 2 ver 10 | | 2 | 15 | doc 2 ver 15 | +----+-----+--------------+ 4 rows in set (0.00 sec) Dann kannst Du mysql> select max(ver) as neuver -> from doc -> where id = 1 -> group by id; +--------+ | neuver | +--------+ | 2 | +--------+ 1 row in set (0.00 sec) um die maximale Versionsnummer zu einem Dokument $suchid herauszufinden. Weiter kannst Du auch mysql> select id, max(ver) as neuver -> from doc -> group by id; +----+--------+ | id | neuver | +----+--------+ | 1 | 2 | | 2 | 15 | +----+--------+ 2 rows in set (0.00 sec) um eine Liste aller Dokument mit ihren jeweils neuesten Versionen zu bekommen. Aber wie man leicht sieht, geht mysql> select id, max(ver) as neuver, daten -> from doc -> group by id; +----+--------+--------------+ | id | neuver | daten | +----+--------+--------------+ | 1 | 2 | doc 1 ver 1 | | 2 | 15 | doc 2 ver 10 | +----+--------+--------------+ 2 rows in set (0.00 sec) ins Auge. Mit einem Selfjoin könntest Du jedoch auch die anderen Daten dieser Dokumente bekommen, wenn man in einem where group functions verwenden könnte: mysql> select s.* -> from doc as p, doc as s -> where p.id = s.id and s.ver = max(p.ver) -> group by p.id; ERROR 1111: Invalid use of group function Was leider nicht geht. Man kann natürlich voll ausmultiplizieren und dann mit HAVING arbeiten, aber effizent ist das nicht. > Zu allem Überfluss hätte ich das ganze auch noch am liebsten in möglichst > DB-unabhängigem SQL, d.h. irgendwelche "proprietären" Erweiterungen kommen nicht > in Betracht, da das Skript unverändert (dank PHPLIB) gegen MySQL und ODBC läuft. Mit einem Subselect könnte man es vielleicht hinbekommen, aber MySQL kann keine Subselects: mysql> select id, max(ver) as neuver -> from doc -> group by id; +----+--------+ | id | neuver | +----+--------+ | 1 | 2 | | 2 | 15 | +----+--------+ 2 rows in set (0.00 sec) liefert ja was Du brauchst, also willst Du ja alle Datensätze in denen die von dem o.a. SQL gefundenen Key verwendet werden: select * from doc where id = ( select id from doc group by id ) and ver = ( select max(ver) from doc group by id); Kristian -- Kristian Köhntopp, NetUSE Kommunikationstechnologie GmbH Siemenswall, D-24107 Kiel, Germany, +49 431 386 436 00 Using PHP3? See our web development library at http://phplib.shonline.de/ (GPL)
php::bar PHP Wiki - Listenarchive