Zugriff auf berechnete Datumsspalte in WHERE Klausel
Andreas Kretschmer
andreas.kretschmer at schollglas.com
Di Mär 16 14:37:20 CET 2010
In response to Tim :
> Hallo Andreas,
>
>
> > > SELECT S.datetime_from, S.datetime_to,
> > > IFNULL(DATE_ADD(S.datetime_to, INTERVAL -1 SECOND),
> > > '0000-00-00 00:00:00') as datetime_to_enc
> > > FROM `stocks` S
> > > WHERE datetime_to_enc >= '2010-03-18 14:59:59'
>
>
> > Das ist so richtig, per SQL-Spec. Wenn Du das willst, mach ein
> > Subselect
> > draus. Select * from (deine query ohne where) foo where
> > datetime_to_enc = ...
>
> Ich weiß jetzt nicht so richtig, wie Du das mit dem Subselect meinst.
test=# create table foo (a int, b int);
CREATE TABLE
test=# select a*b as c from foo where c=4;
ERROR: column "c" does not exist
LINE 1: select a*b as c from foo where c=4;
^
test=# select a*b as c from foo where a*b=4;
c
---
(0 rows)
test=# select * from (select a*b as c from foo) bla where c=4;
c
---
(0 rows)
Siehst Du nun das Subselect?
> Hintergrund dieser gesamten Geschichte ist, dass ich Dinge vermiete, die
> raus gegeben werden und an anderen Tagen wieder zurück gegeben werden.
> Und zwar im Prinzip stundengenau. Jetzt ist es in den Beständen aber
> dummerweise so, dass immer die vollen Uhrzeiten abgespeichert werden.
> Also z.B.
>
> datetime_from 2010-03-15 12:00:00
> datetime_to 2010-03-15 15:00:00
Andere Systeme bieten einen Datentyp 'PERIOD', der sowas besser
handhabt.
>
> Bei Fällen, bei denen das Enddatum des einen mit dem Startdatum eines
> anderen Verleihvorgangs zusammenfallen, besteht nun das Problem, dass
> ein Bestand fälschlicherweise doppelt gezählt wird - ich mach das mal
> als Zeitstrahl, die Zahlen in Klammern sind die Anzahlen, die vermietet
> werden:
PERIOD macht das richtig.
>
> (-1) -----------|
> |------------------ (-1)
> ^16:00
>
> Dann ist die Summe des Bestandes für 16:00 Uhr fälschlicherweise -2 und
> nicht -1, weil beide Zeitpunkte - der Startzeitpunkt von B und der
> Endzeitpunkt von A nominell zusammen fallen. Ich wollte das Problem
> dadurch lösen, dass die Spalte datetime_to (also den Endzeitpunkt), auf
> die sich die WHERE-Klausel bezieht, zuvor künstlich um eine Sekunde
> reduziere, sodass sich die Uhrzeiten nicht mehr überschneiden, denn der
> Gegenstand wurde ja im normalen Sprachgebrauch "bis" 16:00 Uhr zurück
> gegeben (also genau genommen bis 15:59:59) und steht dann "um" 16:00 Uhr
> natürlich ebenfalls mit -1 im Bestand. Mein Problem besteht nun mal
> darin, dass in der Tabelle die vollen Stunden drin stehen und um die
> Frage, ob man das quasi während der Laufzeit einer Abfrage umbiegen
> kann, oder ob ich ggf. die Spalte datetime_to_enc noch zusätzlich in die
> Tabelle aufnehme und zur direkten Berechnung verwende. Dann müsste ich
> das natürlich beim Speichern des Datensatzes schon berücksichtigen.
Ich würde PostgreSQL 9.0 mit Exclusion Constraint und PERIOD als
Datentyp verwenden, dann verhindert die DB gleich noch eine
Doppelausleihe und es können auf PERIOD auch Indexe verwendt werden.
http://www.depesz.com/index.php/2010/01/03/waiting-for-8-5-exclusion-constraints/
Andreas
--
Andreas Kretschmer
Kontakt: Heynitz: 035242/47150, D1: 0160/7141639 (mehr: -> Header)
GnuPG: 0x31720C99, 1006 CCB4 A326 1D42 6431 2EB0 389D 1DC2 3172 0C99