ugrás a tartalomhoz

Gyorsabb lekérdezés

mahoo · 2014. Jan. 31. (P), 09.10
Sziasztok, az lenne a kérdésem, hogy mi az optimális lekérdezés az alábbi adatok alapján. Azokra az epületekre lenne szükségem, ahol egy adott időintervallumban (:start, :stop) nincs tanítási óra. Köszönöm!
iskola: idiskola
terem:  idterem, idepulet
tanora: idterem, start, stop
Ez van jelenleg:
SELECT idiskola FROM iskola WHERE idiskola NOT IN (
	SELECT idiskola FROM iskola INNER JOIN terem USING (idiskola) INNER JOIN ora USING (idterem)
		WHERE :start BETWEEN start AND stop OR :stop BETWEEN start AND stop OR :start < start AND stop > :stop)
 
1

Kedves Mahoo!Nem tudom,

tisch.david · 2014. Jan. 31. (P), 10.06
Kedves Mahoo!

Nem tudom, hogy a végrehajtás szempontjából van-e lényeges különbség a kettő között, de ha szeretnéd kidobni a subselectet, akkor ugyanezt így is felírhatnád, JOIN-ok segítségével:

SELECT I.*, I2.id
FROM iskola I
  LEFT JOIN iskola I2 ON I2.id = I.id
    JOIN terem T ON T.iskolaid = I2.id
      JOIN ora O ON O.teremid = T.id AND O.start <= @start AND O.stop > @start
WHERE I2.id IS NULL;
Nem próbáltam, csak fejben raktam össze, úgyhogy remélem nem hibáztam benne.
Üdv:
Dávid
6

Kérhetnék még egy kis

mahoo · 2014. Jan. 31. (P), 15.00
Kérhetnék még egy kis segítéseget? Összeraktam a mintát itt, de valami nem jó és nem sikerül megoldanom.

http://sqlfiddle.com/#!2/8a42fe/2

Illetve szerintem csak elírtad, és nem
O.start <= @start
hanem
O.start <= @stop
. Pontosabb szerintem elég csak a kisebb operátor
O.start < @stop
. Vagy rosszul gondolom?
2

csak egy kis logika :D

szabo.b.gabor · 2014. Jan. 31. (P), 10.13
a not in helyett csinálj egy left join-t és nézd meg, hogy hol null, azaz inkább vedd a feltételed ellentettjét, használd ezt a formulát

!(A || B) = !A && !B

tehát

(:start > start && :start < stop) ||
(:stop > start && :stop < stop) ||
(:start < start && :stop > stop)

ezt kell negálnod (az ellentettjét venned)

!(:start > start && :start < stop) &&
!(:stop > start && :stop < stop) &&
!(:start < start && :stop > stop)

a külön részekre is alkalmazva a szabályt

(:start <= start || :start >= stop) &&
(:stop <= start || :stop >= stop) &&
(:start >= start || :stop <= stop)

elvileg ez az amit keresel, de azért jó lenne, ha egy aktuálisan ezt tanuló kolléga megerősítene, mert ezt most elég régi emlékek alapján vezettem le az öröm kedvéért.

ennek SQL való lefordítása gondolom nem probléma, tehát ez lesz a where feltételed. azt hiszem az is segít, ha nem where-be írod a feltételt, hanem már a JOIN-ba berakod ON-nal, hiszen ilyenkor nem kell az összeset összejoinolnia, és azt szűrni, hanem rögtön a szűrt elemek jelennek meg.
3

2 - 0 a LEFT JOIN is NULL-nak

mahoo · 2014. Jan. 31. (P), 10.30
Akkor átírom a lekérdezést, köszönöm a tanácsokat!!!
4

Egyszerűbb feltétel

csla · 2014. Jan. 31. (P), 10.51
Egyszerűbb feltétel is elég az átfedés vizsgálatához:
start < :stop AND stop > :start
5

Ez tényleg egyszerűbb...

mahoo · 2014. Jan. 31. (P), 11.17
Ez tényleg egyszerűbb... köszi :).
7

Feltételek száma

Vilmos · 2014. Feb. 1. (Szo), 00.48
Azt hiszem, az első megközelítés teljesebb volt mint a többi lekérdezés, legalábbis annak tűnik. Jobban körbejárja a problémát, vagy valami ilyesmi.

Arról nincs szó, hogyan fedhetik át egymást az időpontok, mondjuk minden megengedett. Ha feltételezem, hogy nemcsak egy órát lehet foglalni - az intervallumos tárolás ezt megengedi - akkor az átfedéseket négy vizsgálattal lehet kiszűrni. (Két feltétel kevés, a három érthetetlen.)

1. és 2. feltétel, az időpont kérés kezdete vagy vége tanítási időre esik. Ez bármilyen kombinációban kizáró ok.

tanításra foglalt:     start...stop   start...stop      start............stop
    időpont kérés:  start...stop         start...stop        start...stop      
3. és 4. feltétel, a tanítási óra benne van a lefoglalandó intervallumban. Fordított vizsgálat, a tanítás kezdete vagy vége foglalási pontok között van.

tanításra foglalt:        start...stop
    időpont kérés:   start............stop 
A lekérdezés hibája más kérdés. Ha megengedsz egy tippet, próbáld meg belülről kifelé felépíteni a SELECT-et. Elsőnek az órák szűrése, utána a többi kapcsolat.
8

Csak annak tűnik. :)

csla · 2014. Feb. 1. (Szo), 11.33
Vilmos, vizsgáld meg az általad felvázolt négy lehetőséget, és meglátod, mindegyikre igaz a két feltétel: a kért időpont vége később van, mint a foglalt időpont kezdete (1. feltétel) és a kért időpont kezdete előbb van, mint a foglalt időpont vége (2. feltétel).
9

Ravasz

Vilmos · 2014. Feb. 1. (Szo), 12.58
Tényleg elég, kár hogy teljes kifejezésben nem ez szerepelt.
10

Valaki esetleg rá nézne erre,

mahoo · 2014. Feb. 1. (Szo), 13.01
Valaki esetleg rá nézne erre, hogy mi lehet a gond: http://sqlfiddle.com/#!2/8a42fe/2
11

LEFT JOIN

Vilmos · 2014. Feb. 2. (V), 00.51
Így lett jó:

SELECT * FROM iskola
         JOIN terem ON terem.idiskola = iskola.idiskola
         LEFT JOIN tanora ON tanora.idterem = terem.idterem AND
         '2014-01-30 11:00:00' >= tanora.start AND '2014-01-30 10:00:00' <= tanora.stop
WHERE tanora.idterem IS NULL
Az iskola-tábla nincs benne kétszer, ez mondjuk talán mindegy. (1.)
A feltételt átrendeztem éles eszű barátunk magyarázata szerint. (4. 8.)

A lényeg, az IS NULL feltétel a tanora-táblára alkalmazandó!
12

Köszönöm, jónak néz ki! Még

mahoo · 2014. Feb. 2. (V), 21.17
Köszönöm, jónak néz ki! Még azért tesztelgetem...