Ako imamo zadat period, prvo treba da utvrdimo koji gosti su bili prijavljeni u tom periodu. To je ono sto monstruozni izraz sa IIF pokusava da postigne. Lakse je ako se logika smesti u WHERE deo iskaza nego u SELECT, ali nije nsita manje monstruzono.
Ajde da nacrtamo sliku, vremensku osu i neke intervale, recimo [---] predstavlja interval kada je gost bio prijavljen. Evo 4 itervala kad smo imali goste:
---------[----]-------[----]--------[------]------[------]-------------> vreme
Oznacimo s {----} interval u kome posmatramo nasu osu, ovako:
---------[----]--{-----[----]--------[---}---]-------[------]-------------> vreme
Ovde imamo da prvi i poslednji [] interval ne upadaju u trazeni period, drugi upada ceo a treci samo delimicno. Moguce su mnoge druge kombinacije. Lakse ce biti da posmatramo samo jedan interval [] i jedan interval {} tipa. Koji su sve moguci odnosi?
Ako je [ = X ]=y i { = A i } = B mozmeo da kazemo:
Slika 1), moguci slucajevi poklapanja intervala:
-------[----{---]---}-----> [X,Y] se preklapa sa {A,B} jer je X<A<Y<B
-------[---{--}--]---------> [X,Y] se preklapa sa {A,B} je je {A,B} ceo unutar [X,Y]
-------{---[----}---]------> [X,Y] s epreklapa sa {A,B} jer je A<X<B<Y
-------{---[---]----}------> [X,Y] se preklapa sa {A,B} jer je ceo [X,Y] unutar {A,B}
To je to sto se tice preklapanja, nema vise slucajeva. Naravno da bismo mogli uvek da napisemo ovakav izraz koji ce pokazati intervale [X,Y] koji se preklapaju sa {A,B}
SELECT
X,Y
FROM NekaTabela
WHERE (X<A AND Y<B)
OR (X <A AND A<B AND B<Y)
OR (A<X AND X<B AND B<Y)
OR (A < X AND X<Y AND Y<B)
Lepo. Ali moze lakse. Nartajmo sliku koja pokazuje kada se dva intervala NE PREKLAPAJU. Postoje samo dva moguca slucaja:
Sklika 2, slucajevi kada se intervali NE preklapaju:
-------{-----}-----[-----]------> {A,B} je ceo ispred [X,Y]
-------[------]----{-----}------> {A,B} je ceo iza [X,Y]
Ovako pokazujemo intervale koji se NE preklapaju sa A,B:
SELECT
X,Y
FROM NekaTabela
WHERE B<X OR A>Y
Ako primenimo NOT operator, intervale koji se preklapaju mozemo dobiti ovako:
SELECT
X,Y
FROM NekaTabela
WHERE NOT(B<X OR A>Y)
Sve sto treba zapamtiti jeste slika 2.
Idemo na konkretan primer, u zakacenoj bazi. Zelim da vidim sve goste koji su bili prijavljeni u intervalu {A,B} = {#1 Sep 2009#,#15 Sep 2009#}. Intervali [X,Y] su u kolonama [datum_Priojave, Datum_odjave]
Svi gosti koji su bili prijavljeni u intervalu {#1 Sep 2009#, #15 Sep 2009#} dobijaju se ovako:
SELECT
*
FROM tblGosti
WHERE NOT (#15 Sep 2009# < Datum_Prijave OR #1 Sep 2009#>Datum_Odjave)
Dalje je lako, COUNT(*) sa GROUP BY po sifri drzave.
Sve u svemu:
Code:
SELECT tblGosti.Sifra, tblGosti.Sifra_Drzava, tblGosti.Ime, tblGosti.Datum_odjave, tblGosti.Datum_prijave
FROM tblGosti
WHERE NOT ([Pocetak Intervala]>[tblGosti].[Datum_odjave] OR tblGosti.Datum_prijave>[Kraj Intervala]);
ili ovo
Code:
SELECT tblGosti.Sifra_Drzava, Count(*) AS BrojGostiju
FROM tblGosti
WHERE NOT ([Pocetak Intervala]>[tblGosti].[Datum_odjave] OR tblGosti.Datum_prijave>[Kraj Intervala])
GROUP BY tblGosti.Sifra_Drzava;
Zakaceni primer daje za nijansu lepse izlazne rezultete - vidi se preiood za koji brojimo goste.