Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Überschneidung von Datumsbereichen finden? (https://www.delphipraxis.net/21652-ueberschneidung-von-datumsbereichen-finden.html)

Sharky 6. Mai 2004 06:15


Überschneidung von Datumsbereichen finden?
 
Hai,

ich programmiere gerade ein Raumbuchungssystem. In der Tabelle mit den Buchungen habe ich zwei Datumswerten (von , bis).
Wenn jetzt eine neue Buchung für diesen Raum gemacht wird möchte ich prüfen ob der Raum zu diesem Zeitpunkt schon belegt ist.
Leider stehe ich total auf dem Schlauch heute Morgen :stupid:

z.B.:

Raum 1 ist gebucht von 06.05.2004 10:30 bis 08.05.2004 18:00

Wenn jetzt jemand den Raum von 07.05.2004 12:00 bis 09.05.2004 17:30 buchen möchte muss er eine Meldung bekommen das der Raum zu diesem Zeitpunkt schon belegt ist.
  • Datenbank: mySQL
  • Zugriff: Zeos

Kann mir jemand auf die Sprünge helfen? Danke :-D

Robert_G 6. Mai 2004 06:20

Re: Überschneidung von Datumsbereichen finden?
 
Ist etwas früh , aber vielleicht geht das:
SQL-Code:
SELECT *
FROM  DeineTabelle t
WHERE t.StartDTM < :i_EndDTM And t.EndDTM > :i_StartDTM

alcaeus 6. Mai 2004 06:22

Re: Überschneidung von Datumsbereichen finden?
 
Ich hab sowas für meine Autovermietung gebraucht...ich habs aber im Programm abgefragt und nicht in SQL
Also:
IntStart1 = 06.05.2004 10:30
IntEnde1 = 08.05.2004 18:00
IntStart2 = 07.05.2004 12:00
IntEnde2 = 09.05.2004 17:30

Die Abfrage hat bei mir so gefunzt:
Delphi-Quellcode:
if (IntStart1 in [IntStart2..IntEnde2]) or (IntStart2 in [IntStart1..IntEnde1]) then
  ShowMessage(Intervallüberlappung');
Ich hab nur der Kürze wegen in verwendet, in Delphi funzt das nicht, da TDateTime ja Double ist. Deshalb musst du mit >= und <= arbeiten.

Dadurch wird abgefangen ob Int1 in Int2 liegt und umgekehrt
[edit]Noch eine Erklärung und den Code vervollständigt ;)[/edit]

MarkusB 6. Mai 2004 06:47

Re: Überschneidung von Datumsbereichen finden?
 
Hi!

Ich würde das so versuchen:
SQL-Code:
...
where BuchungStart between NeueBuchungStart and NeueBuchungEnd
   or BuchungEnd  between NeueBuchungStart and NeueBuchungEnd
...
Viele Grüße
Markus :gruebel:

Luciano 6. Mai 2004 07:33

Re: Überschneidung von Datumsbereichen finden?
 
Hi...

Das mit dem Kleiner und Größer müßte eigentlich "kleiner gleich" und "größer gleich" heißen, wenn ich mich auf die schnelle nicht irre

Delphi-Quellcode:
  bisDatum := DateTimePicker8.Date;
  vonDatum := DateTimePicker7.Date;

  Anfrage1 := (' SELECT * FROM RESERVIE '+
               ' WHERE (ANREISE >= '+QuotedStr(DateToStr(vonDatum))+
               ' AND '+
               ' ANREISE >= '+QuotedStr(DateToStr(bisDatum))+')'+
               ' OR '+
               ' (ABREISE >= '+QuotedStr(DateToStr(vonDatum))+
               ' AND '+
               ' ABREISE <= '+QuotedStr(DateToStr(bisDatum))+')'+
               ' ORDER BY ANREISE, ABREISE ');
Das ist ein Reservierungsplan... Listet mir alle An- und Abreisen zwischen dem ausgewählten Datum auf. Sollte eigentlich auch bei dir funktionieren!

Greets

Luciano

Sharky 6. Mai 2004 07:38

Re: Überschneidung von Datumsbereichen finden?
 
Danke euch,

ich werde es gleich einmal testen. Aber vorher brauche ich einen Kaffee. :roteyes:

Robert_G 6. Mai 2004 07:58

Re: Überschneidung von Datumsbereichen finden?
 
@Luciano
Natürlich hast du recht, ABER ...
Delphi-Quellcode:
  ...
  ' ANREISE >= '+QuotedStr(DateToStr(bisDatum))+')'+
  ...
.. sowas ist nicht nur generell Unsinn, mit einem Datumsfeld gehen diese Stringbasteleien auch noch mit 100%-iger in die Hose, wenn auch nur einer der Clients andere Regionaleinstellungen als der DB-Server hat.

Also:
SQL-Code:
SELECT *
FROM  DeineTabelle t
WHERE t.StartDTM <= :i_EndDTM And t.EndDTM >= :i_StartDTM

Sharky 6. Mai 2004 08:07

Re: Überschneidung von Datumsbereichen finden?
 
Ich denke die Methode von Markus sieht ganz gut aus und funktioniert zumindest via MySQL-Control-Center wunderbar.

Delphi-Quellcode:
begin
  Query1.Close;
  Query1.SQL.Text := 'SELECT * FROM buchungen';
  Query1.Sql.Add ('WHERE ((BuchungStart BETWEEN :NeueBuchungStart and :NeueBuchungEnd)');
  Query1.Sql.Add ('OR (BuchungEnd BETWEEN :NeueBuchungStart and :NeueBuchungEnd))';
  Query1.Sql.Add ('AND (raum_id=:raum_id) AND (buchungs_id <> :buchungs_id)');
  Query1.ParamByName ('NeueBuchungStart').AsDateTime := start;
  Query1.ParamByName ('NeueBuchungEnde').AsDateTime := ende;
  Query1.ParamByName ('raum_id').AsInteger := raum_id;
  Query1.ParamByName ('buchungs_id').AsInteger := buchungs_id;
  Open;
end;
raum_id ist die ID des Raumes den ich buchen möchte.
buchungs_id brauche ich um, bei einer änderung der Buchung, nicht die eigene zu finden.

Luciano 6. Mai 2004 08:29

Re: Überschneidung von Datumsbereichen finden?
 
@Robert_G

Da hast du recht, mit den String.... :idea: für mehrere Clients ist das nicht gerade von Vorteil. Das Programm läuft bei mir allerdings nur auf MSDE lokal ohne andere Clients.

Greets


Luciano

MarkusB 6. Mai 2004 20:27

Re: Überschneidung von Datumsbereichen finden?
 
Hallo nochmal!

Ich habe festgestellt, dass die von mir vorher vorgeschlagene Methode nicht alle möglichen Fälle abdeckt. :oops:
Die folgende Version sollte „wasserdicht“ sein:

SQL-Code:
where ( 
        (BuchungStart between NeueBuchungStart and NeueBuchungEnd)
        or
        (BuchungEnd  between NeueBuchungStart and NeueBuchungEnd)
        or
        (BuchungStart <= NeueBuchungStart and BuchungEnd >= NeueBuchungEnd)
      )
Viele Grüße
Markus
:gruebel:

alcaeus 6. Mai 2004 20:31

Re: Überschneidung von Datumsbereichen finden?
 
Zitat:

Zitat von MarkusB
SQL-Code:
where ( 
        (BuchungStart between NeueBuchungStart and NeueBuchungEnd)
        or
        (BuchungEnd  between NeueBuchungStart and NeueBuchungEnd)
        or
        (BuchungStart <= NeueBuchungStart and BuchungEnd >= NeueBuchungEnd)
      )

Du kannst dir aber auch eine Abfrage sparen:

SQL-Code:
where ( 
       (BuchungStart    between NeueBuchungStart and NeueBuchungEnd)
       or
       (NeueBuchungStart between BuchungStart    and BuchungEnd)
     )

MarkusB 6. Mai 2004 20:41

Re: Überschneidung von Datumsbereichen finden?
 
Hallo alcaeus!

Leider nicht. :)

Überleg mal:
Wie willst Du ein Zimmer von Mittwoch bis Donnerstag buchen, das aber von Dienstag bis Freitag schon gebucht ist?

Viele Grüße
Markus
:gruebel:

alcaeus 6. Mai 2004 20:46

Re: Überschneidung von Datumsbereichen finden?
 
Na dann ist ja NeueBuchungStart zwischen BuchungStart und BuchungEnd,oder?

Hier ne Skizze:

Code:
---------------
| NeueBuchung |
---------------
     -------------
     |  Buchung |
     -------------
Hier ist BuchungStart zwischen NeueBuchungStart und NeueBuchungEnd => erkannt

---------------
|   Buchung  |
---------------
     ---------------
     | NeueBuchung |
     ---------------
Hier ist NeueBuchungStart zwischen BuchungStart und BuchungEnd => erkannt

  ---------------
  |   Buchung  |
  ---------------
-------------------
|   NeueBuchung  |
-------------------
Hier ist BuchungStart zwischen NeueBuchungStart und NeueBuchungEnd => erkannt

  ---------------
  | NeueBuchung |
  ---------------
-------------------
|     Buchung    |
-------------------
Hier ist NeueBuchungStart zwischen BuchungStart und BuchungEnd => erkannt
Ich hoffe das hilft, das Schema zu erklären...

Robert_G 6. Mai 2004 21:15

Re: Überschneidung von Datumsbereichen finden?
 
Wir hatten hier schon einmal fast die gleiche Diskussion. Ich vertrat erst Marskus' Meinnug, musste aber doch einsehen, dass TreffNix Recht hatte.
Seine Lösung sah IMHO so aus (auf jeden Fall wird das Statement funktionieren ;) ):
SQL-Code:
SELECT * 
FROM  DeineTabelle t
WHERE t.StartDTM <= :i_EndDTM And t.EndDTM >= :i_StartDTM

Leuselator 6. Mai 2004 21:44

Re: Überschneidung von Datumsbereichen finden?
 
Datumsbereiche sind echt die Hölle - besonders, wenn sich mehrere Tabellen gegenseitig beeinflußen, Ende-Daten auch leer (NULL) sein können (= bis auf weiteres gültig) und man sicherstellen muß, dass zu einem gegebenen Zeitpunkt genau eine priorisierte Zuordnung vorhanden ist (z.B. Kunde mit mehreren Bankverbindungen - genau eine wird für Einzug genutzt, die anderen sind dann inaktiv - nun kommt eine Neue Bankverbindung hinzu und die soll in einem in der Zukunft liegenden Zeitabschnitt prisorisiert werden, danach soll aber wieder die alte Bankverbindung benutzt werden, ohne dass... :kotz: )

Habe mir eine Funktion gebastelt, die mir da etwas hülft (MSSQL): (*AusNähkästchenKram*)
SQL-Code:
-- liefert 1 zurück, wenn A irgendwie B überlappt, sonst 0
CREATE FUNCTION dbo.fx_A_Hits_B
( @AStart datetime
, @AStop datetime
, @BStart datetime
, @BStop datetime)
RETURNS bit AS
BEGIN
  DECLARE @EndOfTime datetime
        , @BeginOfTime datetime
      SET @EndOfTime  = 2958463 -- = 31.12.9999
      SET @BeginOfTime = -53690 -- = 01.01.1753
RETURN (CASE WHEN @AStart < coalesce(@BStop,@EndOfTime)
              AND coalesce(@AStop,@EndOfTime) > coalesce(@BStart,@BeginOfTime)
             THEN 1
             ELSE 0
        END)
END
Gruß

PS: Achso - ich habe in meiner DB alles auf 0:00:00.000 Uhr (Start) bzw. 23:59:59.997 (Stop) gesetzt - daher kein <= und >= sondern nur < und >

MarkusB 6. Mai 2004 22:13

Re: Überschneidung von Datumsbereichen finden?
 
Hi!

@ alcaeus
Du hast den Spaltennamen und den Prüfwert vertauscht und das ist nicht zulässig.
Laut http://www.w3schools.com/sql/sql_between.asp sieht eine gültige Syntax folgendermaßen aus:

SQL-Code:
SELECT column_name FROM table_name
WHERE column_name
BETWEEN value1 AND value2
@ Robert :thuimb:

Viele Grüße
Markus
:gruebel:

alcaeus 7. Mai 2004 05:58

Re: Überschneidung von Datumsbereichen finden?
 
Zitat:

Zitat von MarkusB
Hi!

@ alcaeus
Du hast den Spaltennamen und den Prüfwert vertauscht und das ist nicht zulässig.
Laut http://www.w3schools.com/sql/sql_between.asp sieht eine gültige Syntax folgendermaßen aus:

SQL-Code:
SELECT column_name FROM table_name
WHERE column_name
BETWEEN value1 AND value2
@ Robert :thuimb:

Viele Grüße
Markus
:gruebel:

Ich wusste das mit between nicht :oops: Man kann es aber auch mit >= und <= lösen...


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:42 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz