phpbar.de logo

Mailinglisten-Archive

[php] [etwas OT] DB-Zeilen "filtern"

[php] [etwas OT] DB-Zeilen "filtern"

Kristian =?iso-8859-1?Q?K=F6hntopp?= kk_(at)_netuse.de
Wed, 21 Jul 1999 14:11:54 +0200


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