66 lines
2.3 KiB
Markdown
66 lines
2.3 KiB
Markdown
|
+++
|
|||
|
title = "MySQL kann Datensaetze \"zerreissen\""
|
|||
|
date = "2010-04-16T15:12:00+00:00"
|
|||
|
author = "Stormwind"
|
|||
|
draft = false
|
|||
|
+++
|
|||
|
|
|||
|
Dass MySQL eine - nun sagen wir - seltsame Datenbank ist, dürfte ja
|
|||
|
hinreichend bekannt sein.
|
|||
|
|
|||
|
Aber mir ist etwas untergekommen, was selbst ich nicht für möglich
|
|||
|
gehalten hätte.
|
|||
|
|
|||
|
Man stelle sich also eine Tabelle vor in der eine Spalte mehrere gleiche
|
|||
|
Werte behinhalten kann und eine weitere das Datum dazu. Ich wollte also
|
|||
|
auf diese gleichen Werte gruppieren und dabei aber den Datensatz mit dem
|
|||
|
höchsten Datum erhalten.
|
|||
|
|
|||
|
Das alles könnte ich nun mit
|
|||
|
[OVER](http://en.wikipedia.org/wiki/Select_%28SQL%29#Window_function)
|
|||
|
machen… was MySQL aber nicht beherrscht.
|
|||
|
|
|||
|
Also musste ich mir etwas anderes einfallen lassen.
|
|||
|
|
|||
|
MySQL lässt es unvernünfitger Weise zu, dass wenn man ein GROUP BY
|
|||
|
benutzt, man trotzdem alle möglichen Spalten auswählen kann. Und ich
|
|||
|
dachte ich mache mir das zu Nutze indem ich einfach bei den Ausgaben ein
|
|||
|
`MAX(datum)` einfüge. Nach den Gesetzen der Logik müsste es ja dann den
|
|||
|
Datensatz ausspucken, der das höchste Datum hat.
|
|||
|
|
|||
|
Also nehmen bei Beispielsweise eine Tabelle mit 3 Spalten:
|
|||
|
|
|||
|
<source:sql>\
|
|||
|
create table testmax(projekt varchar(10), important\_value integer,
|
|||
|
datum integer);\
|
|||
|
insert into testmax values (‘projekt1’, 1, 1000), (‘projekt1’, 2, 1001),
|
|||
|
(‘projekt1’, 3, 1010), (‘projekt2’, 1, 1000), (‘projekt2’, 2, 1111);\
|
|||
|
</source>
|
|||
|
|
|||
|
Und Probieren folgenden select aus:
|
|||
|
|
|||
|
<source:sql>select projekt, important\_value, max(datum) from testmax
|
|||
|
group by projekt;</source>
|
|||
|
|
|||
|
Und nun passiert was, was meiner Meinung nacht gar nicht gehen dürfte.
|
|||
|
Die Datenbank zerreißt die Datensätze und fügt sie für diesen Select neu
|
|||
|
zusammen.
|
|||
|
|
|||
|
So bekomme ich gar nicht den erwünschten Wert von “important\_value”
|
|||
|
sondern den erstbesten, den die MySQL-Datenbank zu greifen bekommt,
|
|||
|
obwohl ich gleichzeitig das aktuellste Datum angezeigt bekomme.
|
|||
|
|
|||
|
**Ergebnis:**
|
|||
|
|
|||
|
projekt important\_value max(datum)
|
|||
|
---------- ------------------ ------------
|
|||
|
projekt1 1 1010
|
|||
|
projekt2 1 1111
|
|||
|
|
|||
|
Von daher bleibt es wohl dann doch eher Bug als Feature, dass man bei
|
|||
|
MySQL nach SELECT alle Spalten trotz GROUP BY angeben kann…\
|
|||
|
Das bedeutete für mich, dass ich leider den Riesenumweg über ein
|
|||
|
Subselect machen musste, was das ganze erheblich verlangsamt hat.
|
|||
|
|
|||
|
**Bis denne**
|