Abfrageproblem zwei spalten mit timestamp

xpapa

Neuer Benutzer
Beiträge
3
Für eine Zimmerverwaltung möchte ich die Belegung der Zimmer prüfen. Die Belegungstabelle hat ein startund enddatum sowie die zugehörige Raum-ID. Nun möchte ich checken wie viele Räume frei sind. Irgend wie ist mein Syntax krum bzw will nicht:

SELECT count(r.id) FROM rooms r
LEFT JOIN assignments a ON a.rooms_id = r.id
WHERE ($timestamp NOT BETWEEN start AND end)

start und end sind auch timestamps und $timestamp übergebe ich aktuelle Zeit als timestamp.

Wo ist mein Denkfehler ?
 
Werbung:
Für eine Zimmerverwaltung möchte ich die Belegung der Zimmer prüfen. Die Belegungstabelle hat ein startund enddatum sowie die zugehörige Raum-ID. Nun möchte ich checken wie viele Räume frei sind. Irgend wie ist mein Syntax krum bzw will nicht:

SELECT count(r.id) FROM rooms r
LEFT JOIN assignments a ON a.rooms_id = r.id
WHERE ($timestamp NOT BETWEEN start AND end)

start und end sind auch timestamps und $timestamp übergebe ich aktuelle Zeit als timestamp.

Wo ist mein Denkfehler ?

Was passiert denn?

Ich würde für sowas ja zu PostgreSQL und RANGE-Typen greifen. Um das mal zu zeigen:

Code:
test=*# select * from xpapa ;
 zimmer |  belegt
--------+-------------------------
  1 | [2014-08-01,2014-08-10)
  1 | [2014-08-12,2014-08-20)
  2 | [2014-08-12,2014-08-20)
(3 rows)

Time: 0,235 ms
test=*# select * from xpapa where not belegt  @> '2014-08-03'::date;
 zimmer |  belegt
--------+-------------------------
  1 | [2014-08-12,2014-08-20)
  2 | [2014-08-12,2014-08-20)
(2 rows)

Time: 0,292 ms
test=*# select * from xpapa where not belegt  @> '2014-08-13'::date;
 zimmer |  belegt
--------+-------------------------
  1 | [2014-08-01,2014-08-10)
(1 row)

Da auf der Tabelle ein Exclusion Constraint wie folgt definiert ist:

Code:
test=*# \d xpapa
  Table "public.xpapa"
 Column |  Type  | Modifiers
--------+-----------+-----------
 zimmer | integer  |
 belegt | daterange |
Indexes:
  "xpapa_zimmer_belegt_excl" EXCLUDE USING gist (zimmer WITH =, belegt WITH &&)

kann ein Zimmer auch nicht doppelt belegt werden:

Code:
test=*# insert into xpapa values (2, '[2014-08-02,2014-08-14)');
ERROR:  conflicting key value violates exclusion constraint "xpapa_zimmer_belegt_excl"
DETAIL:  Key (zimmer, belegt)=(2, [2014-08-02,2014-08-14)) conflicts with existing key (zimmer, belegt)=(2, [2014-08-12,2014-08-20)).
Time: 0,385 ms

Schick, oder?
 
Was passiert, er spuckt immer nur count 1 aus obwohl 3 räume vorhanden sind und nur einer eine Reservierung hat.

works for me:

Code:
test=*# select * from rooms ;
 id   
----   
  1   
  2   
  3
  4
  5
(5 rows)

Time: 0,206 ms
test=*# select * from assignments ;
 rooms_id | start | ende | belegt
----------+-------+------+--------
  1 |  2 |  5 | [2,5)
  3 |  3 |  6 | [3,6)
  5 |  4 |  7 | [4,7)
(3 rows)

Time: 0,165 ms
test=*# select count(r.id) from rooms r left join assignments a on a.rooms_id=r.id where 1 not between a.start and a.ende;
 count
-------
  3
(1 row)

Time: 0,385 ms
test=*# select count(r.id) from rooms r left join assignments a on a.rooms_id=r.id where not belegt @> 1;
 count
-------
  3
(1 row)

Time: 0,359 ms
test=*# select count(r.id) from rooms r left join assignments a on a.rooms_id=r.id where 3 not between a.start and a.ende;
 count
-------
  1
(1 row)

Time: 0,386 ms
test=*# select count(r.id) from rooms r left join assignments a on a.rooms_id=r.id where not belegt @> 3;
 count
-------
  1
(1 row)

Time: 0,348 ms
test=*#

Mal extra auch mit start und ende - Feldern und, weil ich ja PG habe, mit Ranges. Der Einfachkeit halber aber mit INT-Werten.
 

Ach quatsch. Du suchst ja auch noch die Datensätze (Zimmer), für die kein Join zustande kommt.
Code:
test=*# select count(r.id) from rooms r left join assignments a on a.rooms_id=r.id where not belegt @> 3 or a.rooms_id is null;
 count
-------
  3
(1 row)

Time: 0,356 ms
test=*# select count(r.id) from rooms r left join assignments a on a.rooms_id=r.id where not belegt @> 1 or a.rooms_id is null;
 count
-------
  5
(1 row)
test=*# select count(*) from rooms r left join assignments a on a.rooms_id=r.id where 1 not between a.start and a.ende or a.rooms_id is null;
 count
-------
  5
(1 row)

Time: 0,413 ms
test=*# select count(*) from rooms r left join assignments a on a.rooms_id=r.id where 3 not between a.start and a.ende or a.rooms_id is null;
 count
-------
  3
(1 row)
 
Ach quatsch. Du suchst ja auch noch die Datensätze (Zimmer), für die kein Join zustande kommt.

Wobei mir eigent das hier besser gefällt:

Code:
test=*# select * from rooms where id not in (select distinct rooms_id from assignments where belegt @> 3);
 id
----
  2
  4
  5
(3 rows)

Time: 0,319 ms
test=*# select * from rooms where id not in (select distinct rooms_id from assignments where 3 between start and ende);
 id
----
  2
  4
  5
(3 rows)
 
Werbung:
Zurück
Oben