Autor Zpráva
Lisoe
Profil *
Zdravím,

rád bych poprosil o radu, mám tabulku reservation (id, date_from, date_to) [date_from a date_to jsou DATETIME]. A já bych potřeboval vždy při odeslání rezervace zkontrolovat, zda odeslaná rezervace nemá již kolizi s jinou rezervací v systému.

Mohu poprosit o radu, jak sestavit správný dotaz?

Moc díky!
Tomášeek
Profil
Lisoe:
Porovnáš zadané datumy s těmi, které jsou v databázi (kolize nastává, pokud je požadovaný začátek později než nějaký v DB a současně požadovaný konec dříve, než zadaný v DB u téhož řádku).

Problém je konkrétně kde? To není o zápisu, ale o velké logice, ale spíše o lenosti.
Joker
Profil
Tomášeek:
kolize nastává, pokud je požadovaný začátek později než nějaký v DB a současně požadovaný konec dříve, než zadaný v DB u téhož řádku

To je jen jedna z možností, i když vyloučí tuhle situaci, pořád může kolize nastat.
Dá se říci, že jsou čtyři druhy kolizí:

Uloženo :     |---------|        
Kolize 1:            |XX-------| (začíná v rezervované době a končí po ní)
Kolize 2: |----XXXXX|            (začíná před a končí v rezervované době)
Kolize 3:        |XXXX|          (celá uvnitř rezervované doby)
Kolize 4:   |--XXXXXXXXX---|     (začíná před a končí po rezervované době)

Čili, když budu říkat „rezervace“ těm už uloženým a „interval“ ten nově požadovaný, šla by kolize dohledat jako rezervace splňující:
• Začátek intervalu leží uvnitř rezervace,
• NEBO Konec intervalu leží uvnitř rezervace,
• (3. typ splní obě předchozí podmínky, takže ten máme vyřešený, )
• NEBO (začátek intervalu je dřív než začátek rezervace a současně konec intervalu je později než konec rezervace)

Takže když nově zadávaný začátek a konec bude NFR a NTO, byla by podmínka na kolizní rezervaci asi takhle:
(NFR >= date_from AND NFR < date_to) OR (NTO > date_from AND NTO <= date_to) OR (NFR <= date_from AND NTO >= date_to)
Kajman
Profil
Kolize nastává, pokud je začátek vkládaného řádku před koncem uloženého řádku a zároveň pokud je konec vkládaného řádku za začátkem toho samého uloženého řádku.

Takto to není někdy na první pohled jasné, ale dá se k tomu dojít i tak, že při hledání kolizí nás nezajímají dříve uložené řádky, které končí před vkládaným intervalem nebo které začínají až po vkladaném intervalu. Všechno ostatní jsou kolize.

Tedy nezajímají nás
`date_to` <= 'NFR' OR `date_from` >= 'NTO'

Negace otočí znaménka a logické operátory a vyjde ta jednoduchá podmínka popsaná v první větě.
`date_to` > 'NFR' AND `date_from` < 'NTO'
TomášK.
Profil *
Pokud by to byl PostgreSQL, jde použít (start1, end1) OVERLAPS (start2, end2)
ZdenekPNJ
Profil
Lisoe:
A nebylo by lepší hned zezačátku vůbec nedat možnost vybrat již rezervovaný termín či čas? Prostě z dostupných rezervací nabídnout již jen ty volné?
Tomášeek
Profil
ZdenekPNJ:
Ne vždy to jde. Navíc ta logika je tam stejná. A ať se kontroluje dopredne, nebo zpetne je už jedno.
Keeehi
Profil
ZdenekPNJ:
Dalším problémem je paralelní zápis. Kontrolovat se to stejně musí i na konci. Protože i když uživateli zobrazíš jen volné termíny a o si nějaký vybere, tak nevíš, zda v době kdy si vybíral neudělal nějaký jiný uživatel rezervaci s kterou to koliduje.
Kajman
Profil
ZdenekPNJ:
U datetime od - do je jen v jednom jediném dni přes 3 miliardy kombinací - z toho bych nechtěl vybírat, raději si budu datetime zadávat.
Tomášeek
Profil
Kajman:
Tak ono to nemusí být tak horké. Např. obě hranice můžou být omezené na celé půlhodiny (HH:00, HH:30). Délka trvání např. 00:30 - 02:00 hod. Pak už těch kombinací je reálný počet a dají se průběžně disablovat dle aktuální situace. Ukládání tohoto jako datetime (včetně data) mi přijde celkem validní.

Vycházím z toho, jak to může fungovat u reálného projektu. U jiného to může fungovat jinak a může jít klidně o milisekundy, tam výběr na místě nebude.
ZdenekPNJ
Profil
Kajman:
jj, chápu, máš pravdu

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0