Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Abfrageproblem zwei spalten mit timestamp

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von xpapa, 20 August 2014.

  1. xpapa

    xpapa Neuer Benutzer

    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 ?
     
  2. akretschmer

    akretschmer Datenbank-Guru

    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?
     
  3. xpapa

    xpapa Neuer Benutzer

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

    akretschmer Datenbank-Guru

    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.
     
  5. akretschmer

    akretschmer Datenbank-Guru

    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)
    
    
    
    
     
  6. akretschmer

    akretschmer Datenbank-Guru

    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)
    
     
  7. xpapa

    xpapa Neuer Benutzer

    Danke so klappt es :D (y)
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden