Prvo probaj resenje. Inace najbolje je da nacrtas i da analiziras. Mozda je moja krivica sto nisam bolje nacrtao ali ako budem imao vremena nacrtacu josa preciznije
SQL Mozgalice, mozgalica broj 4
Zaključano
Zakačeno
Ok, probao, analizirao, i opet mi nije jasno. Pretpostavimo:
1. svaki plavi kvadrat je 10 osoba.
2. crveni kvadrat je 20 osoba.
3. kapacitet restorana je 60 osoba.
Zelenom bojom na slici su označeni oni koji ispunjavaju tvoj uslov. Jesam li u pravu za to?
Njihova suma je 60. Dakle nema mesta za dodatnih 20.
Ali očima kad pogledaš u sliku je jasno da je zauzeto 40 mesta jer se oni koje sam ja dodao ne preklapaju, pa u svakom trenutku imaš maksimalno 40 ljudi, te možemo dodati još 20.
Šta propuštam?
ss.
1. svaki plavi kvadrat je 10 osoba.
2. crveni kvadrat je 20 osoba.
3. kapacitet restorana je 60 osoba.
Zelenom bojom na slici su označeni oni koji ispunjavaju tvoj uslov. Jesam li u pravu za to?
Njihova suma je 60. Dakle nema mesta za dodatnih 20.
Ali očima kad pogledaš u sliku je jasno da je zauzeto 40 mesta jer se oni koje sam ja dodao ne preklapaju, pa u svakom trenutku imaš maksimalno 40 ljudi, te možemo dodati još 20.
Šta propuštam?
ss.
Potpis
When something is hard to do, then it's not worth doing.
@negyxo
Ne radi ti resenje, a evo i zasto:
ti selektujes sumu svih musterija gde je (start_time > @start_time OR end_time > @start_time) AND start_time < @end_time ato je greska.
Zamisli da u tabeli vec imas nekoga ko je bukirao 100 musterija od 1-2 i drugog koje bukirao 100 musterija od 2-3 i ti sada hoces da napravis novu rezervaciju za 50 musterija od 1-3. Posto oba ona intervala imaju preklapanje sa 1-3 onda ces ti da saberes te cifre i dobices 200 i onda ce ispasti da ne mozes da napravis booking iako mozes.
Ne radi ti resenje, a evo i zasto:
ti selektujes sumu svih musterija gde je (start_time > @start_time OR end_time > @start_time) AND start_time < @end_time ato je greska.
Zamisli da u tabeli vec imas nekoga ko je bukirao 100 musterija od 1-2 i drugog koje bukirao 100 musterija od 2-3 i ti sada hoces da napravis novu rezervaciju za 50 musterija od 1-3. Posto oba ona intervala imaju preklapanje sa 1-3 onda ces ti da saberes te cifre i dobices 200 i onda ce ispasti da ne mozes da napravis booking iako mozes.
@srki
OK, jasno mi je sta hoces da kazes. Ja sam gledao samo slucaj preklapanja, nisam vodio racuna o broju gostiju. Inace resenje sam vec imao, gde sam imao slucaj da se trazi preklapanje vremena za odredjeni period pa sam pomislio da je ovo isti slucaj, ali ocigledno da sam se prevario posto broj gostiju je dodatni uslov koji se ne sme zanemariti.
OK, jasno mi je sta hoces da kazes. Ja sam gledao samo slucaj preklapanja, nisam vodio racuna o broju gostiju. Inace resenje sam vec imao, gde sam imao slucaj da se trazi preklapanje vremena za odredjeni period pa sam pomislio da je ovo isti slucaj, ali ocigledno da sam se prevario posto broj gostiju je dodatni uslov koji se ne sme zanemariti.
Citat:
chachka: @srki: Interesantno resenje, mada si nam ga rano prezentovao. Jos se o ovoj mozgalici moglo diskutovati.
U pravu si ali nema brige, imam ja jos dosta mozgalica pa cu sledeci put cekati da se vise razvije diskusija.
Citat:
Pored ovih tacaka mi je bilo bitno da uhvatim i zavrsetak poslednjeg perioda, sto je uradjeno sa MAX:
Code:
SELECT ...
MAX(vr2.end_time)
...
SELECT ...
MAX(vr2.end_time)
...
Mislim da treba min a ne max. Zamisli da imas 3 rezervacije:
1) od 12 do 2, 50 osoba
2) od 12 do 4, 50 osoba
3) od 12 do 6, 50 osoba.
Ako ti hoces da napravis rezervaciju br. 4: od 5 do 6, 150 osoba trebalo bi da mozes ali ispasce da ne mozes.
Code:
SELECT vr1.end_time AS start_time,
MAX(vr2.end_time) AS end_time,
SUM(vr2.broj_musterija_koje_customer_dovodi) AS maksimalan_broj_musterija
SELECT vr1.end_time AS start_time,
MAX(vr2.end_time) AS end_time,
SUM(vr2.broj_musterija_koje_customer_dovodi) AS maksimalan_broj_musterija
Kada je vr1.end_time = 2 (od prvog intervala) ovo ce da ti selektuje ostale 2 i izracunace sumu 100 i postavice start_time na 2 a end_time na 6 (umesto na 4). Posle ce taj inteval da ti ima overlap sa intervalom 5-6 a tu je ta suma 100 umesto 50. Zato tamo moras da stavis MIN ili da i jedno i drugo promenis na ono ranije sto sam predlozio (cini mi se da radi, ne mogu sada da probam jer nemam nikakvu bazu ovde)
izmenjeno 1 put, poslednji put goranvuc 14.03.2007. u 14:06
Izmene poruke
- goranvuc14.03.2007. u 14:06zapis iz teksta poruke
Evo i moj prilog temi. Bila mi je zelja da u "glupom" Accessu (kako ga mnogi zovu) bez namere da bilo sta dokazujem, tj. sa zeljom da na DBMS-u koji ima najmanje mogucnosti resim problem. Takodje sam probao da stvar skroz drugacije postavim, pa sam posao od pretpostavke da nam u stvari treba odgovor na pitanje: Da li postoji neki momenat u nekom intervalu koji ima timeline u preseku sa novim intervalom koji zelimo da bukiramo, a da je u tom momentu broj gostiju + novi broj gostiju > 200 npr.
U nastavku dajem parametrizovani view koji za parametre [OdVremena], [DoVremena] i [BrojNovihGostiju] daje ukupan broj intervala koji su "prebukirani" - naravno, taj broj treba da je 0 ako zelimo da bukiramo odredjeni broj gostiju u odredjenom intervalu.
Dakle Access 2003:
Pokusao sam da struktuiram koliko je to moguce.
Uzeta je u obzir i mogucnost da postoje dva ista intervala, a mozete primetiti da u ovom resenju nije koristen nikakav Max, Min i sl.
U nastavku dajem parametrizovani view koji za parametre [OdVremena], [DoVremena] i [BrojNovihGostiju] daje ukupan broj intervala koji su "prebukirani" - naravno, taj broj treba da je 0 ako zelimo da bukiramo odredjeni broj gostiju u odredjenom intervalu.
Dakle Access 2003:
Code:
SELECT Count(*) AS BrojIntervalaUKomSePrekoracujeBrojGostiju
FROM
(SELECT start_time, end_time,
(SELECT SUM(broj_musterija_koje_customer_dovodi)
FROM vip_restoran AS Podintervali
WHERE
((Podintervali.start_time <= [OdVremena] And Podintervali.end_time > [OdVremena]) OR
(Podintervali.start_time > [OdVremena] And Podintervali.start_time < [DoVremena]))
AND
((Podintervali.start_time <= Intervali.start_time And Podintervali.end_time > Intervali.start_time) OR
(Podintervali.start_time > Intervali.start_time And Podintervali.start_time < Intervali.end_time))
) AS BrojPrisutnihUIntervalu
FROM
(SELECT DISTINCT start_time, end_time
FROM vip_restoran
WHERE
(start_time <= [OdVremena] And end_time > [OdVremena]) OR
(start_time > [OdVremena] And start_time < [DoVremena])
) AS Intervali
) AS MaksimumGostijuPoIntervalima
WHERE (BrojPrisutnihUIntervalu + [BrojNovihGostiju]) > 200
SELECT Count(*) AS BrojIntervalaUKomSePrekoracujeBrojGostiju
FROM
(SELECT start_time, end_time,
(SELECT SUM(broj_musterija_koje_customer_dovodi)
FROM vip_restoran AS Podintervali
WHERE
((Podintervali.start_time <= [OdVremena] And Podintervali.end_time > [OdVremena]) OR
(Podintervali.start_time > [OdVremena] And Podintervali.start_time < [DoVremena]))
AND
((Podintervali.start_time <= Intervali.start_time And Podintervali.end_time > Intervali.start_time) OR
(Podintervali.start_time > Intervali.start_time And Podintervali.start_time < Intervali.end_time))
) AS BrojPrisutnihUIntervalu
FROM
(SELECT DISTINCT start_time, end_time
FROM vip_restoran
WHERE
(start_time <= [OdVremena] And end_time > [OdVremena]) OR
(start_time > [OdVremena] And start_time < [DoVremena])
) AS Intervali
) AS MaksimumGostijuPoIntervalima
WHERE (BrojPrisutnihUIntervalu + [BrojNovihGostiju]) > 200
Pokusao sam da struktuiram koliko je to moguce.
Uzeta je u obzir i mogucnost da postoje dva ista intervala, a mozete primetiti da u ovom resenju nije koristen nikakav Max, Min i sl.
Evo od mene jedna sa kursorima, znam da nije neko elegantno resenje ali gde postoji mogucnost rad sa kursorima, mislim da ce ovo brzo da radi.
E ako sam i sad pogresio, vise se ne javljam
Code:
ALTER FUNCTION [dbo].[CanInsert](@start_time float, @end_time float, @br_musterija int, @max_musterija int)
RETURNS bit
AS
BEGIN
DECLARE columnCursor CURSOR READ_ONLY FOR
SELECT
start_time as startEnd, br_musterija, 1 AS direction
FROM
(SELECT * FROM vip_restoran
WHERE (start_time > @start_time OR end_time > @start_time) AND start_time < @end_time)
AS T
UNION ALL
SELECT
end_time AS startEnd, br_musterija, 0 AS direction
FROM
(SELECT * FROM vip_restoran
WHERE (start_time > @start_time OR end_time > @start_time) AND start_time < @end_time)
AS T
ORDER BY startEnd, direction
DECLARE @ukupanBrojMusterija int,
@startEnd float,
@musterija int,
@direction tinyint,
@canInsert bit
SET @ukupanBrojMusterija = 0
SET @canInsert = 1
OPEN columnCursor
FETCH NEXT FROM columnCursor INTO @startEnd, @musterija, @direction
WHILE (@@fetch_status <> -1)
BEGIN
IF (@@fetch_status <> -2)
BEGIN
IF @direction = 1
SET @ukupanBrojMusterija = @ukupanBrojMusterija + @musterija
ELSE
SET @ukupanBrojMusterija = @ukupanBrojMusterija - @musterija
IF @ukupanBrojMusterija + @br_musterija > @max_musterija
BEGIN
SET @canInsert = 0
BREAK
END
END
FETCH NEXT FROM columnCursor INTO @startEnd, @musterija, @direction
END
CLOSE columnCursor
DEALLOCATE columnCursor
RETURN @canInsert
END
ALTER FUNCTION [dbo].[CanInsert](@start_time float, @end_time float, @br_musterija int, @max_musterija int)
RETURNS bit
AS
BEGIN
DECLARE columnCursor CURSOR READ_ONLY FOR
SELECT
start_time as startEnd, br_musterija, 1 AS direction
FROM
(SELECT * FROM vip_restoran
WHERE (start_time > @start_time OR end_time > @start_time) AND start_time < @end_time)
AS T
UNION ALL
SELECT
end_time AS startEnd, br_musterija, 0 AS direction
FROM
(SELECT * FROM vip_restoran
WHERE (start_time > @start_time OR end_time > @start_time) AND start_time < @end_time)
AS T
ORDER BY startEnd, direction
DECLARE @ukupanBrojMusterija int,
@startEnd float,
@musterija int,
@direction tinyint,
@canInsert bit
SET @ukupanBrojMusterija = 0
SET @canInsert = 1
OPEN columnCursor
FETCH NEXT FROM columnCursor INTO @startEnd, @musterija, @direction
WHILE (@@fetch_status <> -1)
BEGIN
IF (@@fetch_status <> -2)
BEGIN
IF @direction = 1
SET @ukupanBrojMusterija = @ukupanBrojMusterija + @musterija
ELSE
SET @ukupanBrojMusterija = @ukupanBrojMusterija - @musterija
IF @ukupanBrojMusterija + @br_musterija > @max_musterija
BEGIN
SET @canInsert = 0
BREAK
END
END
FETCH NEXT FROM columnCursor INTO @startEnd, @musterija, @direction
END
CLOSE columnCursor
DEALLOCATE columnCursor
RETURN @canInsert
END
E ako sam i sad pogresio, vise se ne javljam
Srki, u pravu si da moje resenje nije ispravno. A tema se rasplamsala bez obzira na tvoje elegantno resenje.
Mrzelo me je da odredujem tacan kraj perioda jer sam mislio da nema uticaja na konacan rezultat, ali sam se prevario.
Da bih istrajao u svojoj ideji upotrebe OVERLAPS operacije, ipak moram odrediti skup perioda ciji je presek prazan skup, a unija skup [MIN(start_time), MAX(end_time)).
To dodatno komplikuje upit, koji sada izgleda:
Ovaj upit je proveren na PostgreSQL 8.1, koji ne podrzava OVER.
Kako izgleda Srkijev upit bez upotrebe OVER-a, to jest sta taj OVER u pozadini radi?
Mrzelo me je da odredujem tacan kraj perioda jer sam mislio da nema uticaja na konacan rezultat, ali sam se prevario.
Da bih istrajao u svojoj ideji upotrebe OVERLAPS operacije, ipak moram odrediti skup perioda ciji je presek prazan skup, a unija skup [MIN(start_time), MAX(end_time)).
To dodatno komplikuje upit, koji sada izgleda:
Code:
SELECT p_max_number - COALESCE(MAX(i.maksimalan_broj_musterija), 0)
FROM (SELECT i3.start_time AS start_time,
i3.end_time AS end_time,
COALESCE(SUM(vr.broj_musterija_koje_customer_dovodi), 0) AS maksimalan_broj_musterija
FROM (SELECT MAX(i2.point_in_time) AS start_time, i1.point_in_time AS end_time
FROM (SELECT start_time AS point_in_time
FROM vip_restoran
UNION
SELECT end_time AS point_in_time
FROM vip_restoran
) AS i1
INNER JOIN
(SELECT start_time AS point_in_time
FROM vip_restoran
UNION
SELECT end_time AS point_in_time
FROM vip_restoran
) AS i2
ON i1.point_in_time > i2.point_in_time
GROUP BY i1.point_in_time
) AS i3
LEFT OUTER JOIN
vip_restoran AS vr
ON (i3.start_time, i3.end_time) OVERLAPS (vr.start_time, vr.end_time)
GROUP BY i3.start_time, i3.end_time
) AS i
WHERE (i.start_time, i.end_time) OVERLAPS (TIMESTAMP p_start_time, TIMESTAMP p_end_time)
SELECT p_max_number - COALESCE(MAX(i.maksimalan_broj_musterija), 0)
FROM (SELECT i3.start_time AS start_time,
i3.end_time AS end_time,
COALESCE(SUM(vr.broj_musterija_koje_customer_dovodi), 0) AS maksimalan_broj_musterija
FROM (SELECT MAX(i2.point_in_time) AS start_time, i1.point_in_time AS end_time
FROM (SELECT start_time AS point_in_time
FROM vip_restoran
UNION
SELECT end_time AS point_in_time
FROM vip_restoran
) AS i1
INNER JOIN
(SELECT start_time AS point_in_time
FROM vip_restoran
UNION
SELECT end_time AS point_in_time
FROM vip_restoran
) AS i2
ON i1.point_in_time > i2.point_in_time
GROUP BY i1.point_in_time
) AS i3
LEFT OUTER JOIN
vip_restoran AS vr
ON (i3.start_time, i3.end_time) OVERLAPS (vr.start_time, vr.end_time)
GROUP BY i3.start_time, i3.end_time
) AS i
WHERE (i.start_time, i.end_time) OVERLAPS (TIMESTAMP p_start_time, TIMESTAMP p_end_time)
Ovaj upit je proveren na PostgreSQL 8.1, koji ne podrzava OVER.
Kako izgleda Srkijev upit bez upotrebe OVER-a, to jest sta taj OVER u pozadini radi?
Potpis
"The best code is no code at all."
- Zidar (ES član)
"Biggest obstacle to learning
SQL is unlearning procedural
programming." - Joe
Celko
"Minimize code, maximize data."
- A. Neil Pappalardo
- Zidar (ES član)
"Biggest obstacle to learning
SQL is unlearning procedural
programming." - Joe
Celko
"Minimize code, maximize data."
- A. Neil Pappalardo
Koliko vidim, ovde vec ima gomila razlicitih resenja, sto je super, ali ko to proverava osim samih autora? Ja sam probao sve moguce varijante test podataka za svoje resenje (koje je usput receno univerzalno, tj. prolazi u vecini sistema, naravno, mislim na sam SQL izraz, a da se ulazni parametri obradjuju od sistema do sistema) i uvek mi vraca ispravne podatke, tako da sam spreman da nagradim simbolicnom novcanom nagradom od 1000 dinara prvog korisnika koji nadje skup podataka za koje moj upit ne vraca ispravan rezultat, a cifra nije losa s obzirom da moze da se zaradi za par minuta.
Koga vredja cifra ne mora da ucestvuje.
Koga vredja cifra ne mora da ucestvuje.
Ja sam ovu funkciju sto sam postovao testirao i mislim da radi ispravni, sa algoritamskog aspekta trebalo bi da je uredu. Sad ono sto mi je zao - je sto nam srki nije ostavio vise vremena, u zurbi da resim nisam ni citao tudja resenja ali sada kada sam pogledao vidim da je srkijevo resenje dosta slicno, ili bolje receno moje resenje dostas slicno srkijevom. E sad, problem na SQL Serveru je sto OVER funkcija ne postoji za agregatne f-je nego samo za ranking f-je. Iskreno ne znam sta radi ta f-ja ali s obzirom da sam pravio resenje preko kursora pretpopstavljam da sumira po koracima.
goranvuc, je l' si siguran da ovo tvoje radi?
Probaj ovo:
rezervacija 1) od 2 do 7, 100 gostiju
rezervacija 2) od 3 do 4, 60 gostiju
rezervacija 3) od 5 do 6, 60 gostiju
Mi hocemo da napravimo novu rezervaciju
Nova rezervacija: od 1 do 8, 40 gostiju
Tu rezervaciju mozemo da napravimo ali mislim da tvoj kod vraca da postoji interval u kome ne mozemo to da napravimo.
Probaj ovo:
rezervacija 1) od 2 do 7, 100 gostiju
rezervacija 2) od 3 do 4, 60 gostiju
rezervacija 3) od 5 do 6, 60 gostiju
Mi hocemo da napravimo novu rezervaciju
Nova rezervacija: od 1 do 8, 40 gostiju
Tu rezervaciju mozemo da napravimo ali mislim da tvoj kod vraca da postoji interval u kome ne mozemo to da napravimo.
@srki, svaka cast!
Evo ja sad gledam, izgleda da je jutro uvek "pametnije" od veceri. Hvala ti puno na trudu, u mom resenju postoji jedan nepokriven slucaj: kada podinterval (interval koji se delimicno preseca sa novim intervalom) sadrzi i sam podintervale koji medjusobno nemaju presek, sto nas dovodi do mogucnosti da taj slucaj postoji i u "dubljim nivoima" tj. da se prenosi na podintervale od podintervala, tako da bi resenje u mom slucaju moralo da bude rekurzivno.
Hvala ti na trudu, dao si i ostalima primer test podataka koje moraju da savladaju. Konkurs zavrsen, salji mi na PP adresu na koju da saljem simblicnu nagradu, a ja idem "da se pokrijem s usima"
Pozdrav!
Evo ja sad gledam, izgleda da je jutro uvek "pametnije" od veceri. Hvala ti puno na trudu, u mom resenju postoji jedan nepokriven slucaj: kada podinterval (interval koji se delimicno preseca sa novim intervalom) sadrzi i sam podintervale koji medjusobno nemaju presek, sto nas dovodi do mogucnosti da taj slucaj postoji i u "dubljim nivoima" tj. da se prenosi na podintervale od podintervala, tako da bi resenje u mom slucaju moralo da bude rekurzivno.
Hvala ti na trudu, dao si i ostalima primer test podataka koje moraju da savladaju. Konkurs zavrsen, salji mi na PP adresu na koju da saljem simblicnu nagradu, a ja idem "da se pokrijem s usima"
Pozdrav!
Nije mi bilo tesko da nadjem primer koji ne radi jer sam vec zbog tog problema na poslu napravio mali milion test primera (da bih dokazao da algoritmi kolega ne rade
) i da bih posle smislio ono jednostavno resenje 
Petsto dinara zadrzi za sebe (zbog truda) a ostalih 500 dinara daj u dobrotvorne svrhe ili pokloni nekom prijatelju/rodjaku kome treba.
Druga opcija je da sve zadrzis za sebe ali da odes u zavod za transfuziju i das krv. Hvala
Petsto dinara zadrzi za sebe (zbog truda) a ostalih 500 dinara daj u dobrotvorne svrhe ili pokloni nekom prijatelju/rodjaku kome treba.
Druga opcija je da sve zadrzis za sebe ali da odes u zavod za transfuziju i das krv. Hvala
Krv svakako dajem dvaput godisnje, imas onda pice kad svratis u Srbiju (sad tek videh odakle se javljas).
Pozdrav!
Vidim da si prilicno pripremljen postavio zadatak, a nas si pustio da se "mozgolomimo"
Pozdrav!
Vidim da si prilicno pripremljen postavio zadatak, a nas si pustio da se "mozgolomimo"
izmenjeno 1 put, poslednji put srki 15.03.2007. u 12:51
Izmene poruke
- srki15.03.2007. u 12:51zapis iz teksta poruke
Znaci castis pivom za 6 meseci, valjda cu imati vremena da svratim do Novog Sada mada mi je krivo sto ne mogu ranije da dodjem zbog Exita, to pre nisam propustao.
Inace ovaj problem je jako cest i resenje je vrlo korisno. Npr. kod prodavanja karata za voz, autobus ili avion, tu imamo umesto vremena redne brojeve stanica i onda kada npr. avion leti od Aucklanda do Londona a slece u Melburnu, Singapuru, Dubaiju i Frankfurtu, neko hoce da uzme kartu od Melburna do Singapura, drugi hoce od Melburna do Dubaija, neko hoce od Singapura do Frankfurta i sl. Tu bi mogao da se primeni ovaj algoritam jer znamo kapacitet aviona i onda tako preletimo kroz ostale rezervacije da bismo videli da li mozemo da napravimo rezervaciju za odredjenu relaciju. Mada ovo je ipak korisnije za vozove koji putuje kroz nekoliko zemalja i obicno staju u svim vecim i nekim manjim gradovima.
Inace ovaj problem je jako cest i resenje je vrlo korisno. Npr. kod prodavanja karata za voz, autobus ili avion, tu imamo umesto vremena redne brojeve stanica i onda kada npr. avion leti od Aucklanda do Londona a slece u Melburnu, Singapuru, Dubaiju i Frankfurtu, neko hoce da uzme kartu od Melburna do Singapura, drugi hoce od Melburna do Dubaija, neko hoce od Singapura do Frankfurta i sl. Tu bi mogao da se primeni ovaj algoritam jer znamo kapacitet aviona i onda tako preletimo kroz ostale rezervacije da bismo videli da li mozemo da napravimo rezervaciju za odredjenu relaciju. Mada ovo je ipak korisnije za vozove koji putuje kroz nekoliko zemalja i obicno staju u svim vecim i nekim manjim gradovima.
izmenjeno 1 put, poslednji put srki 17.03.2007. u 00:45
Izmene poruke
- srki17.03.2007. u 00:45zapis iz teksta poruke
Da, red bi bio da napisem resenje bez upotrebe analitickih funkcija jer nemaju sve baze tu mogucnost.
Nazalost ovo resenje je dosta sporije od resenja koje se dobija koriscenjem analitickih funkcija. MS SQL 2005 podrzava SUM() OVER() sto je ANSI dodatak na sql-99 tako da steta sto ostale baze (osim ORACLE) to ne podrzavaju.
Code:
SELECT MAX(ukupan_broj_musterija)
FROM
( SELECT sum(broj_musterija_koje_customer_dovodi) as ukupan_broj_musterija
FROM
(
SELECT start_time AS vreme1, broj_musterija_koje_customer_dovodi
FROM vip_restoran
UNION ALL
SELECT end_time AS vreme1 , -broj_musterija_koje_customer_dovodi
FROM vip_restoran
UNION ALL
SELECT p_start_time AS vreme1, p_number
FROM DUAL
UNION ALL
SELECT p_end_time AS vreme1, -p_number
FROM DUAL
),
(
SELECT start_time AS vreme2
FROM vip_restoran
UNION ALL
SELECT end_time AS vreme2
FROM vip_restoran
UNION ALL
SELECT p_start_time AS vreme2
FROM DUAL
UNION ALL
SELECT p_end_time AS vreme2
FROM DUAL
)
WHERE vreme1<=vreme2
GROUP BY vreme2
)
SELECT MAX(ukupan_broj_musterija)
FROM
( SELECT sum(broj_musterija_koje_customer_dovodi) as ukupan_broj_musterija
FROM
(
SELECT start_time AS vreme1, broj_musterija_koje_customer_dovodi
FROM vip_restoran
UNION ALL
SELECT end_time AS vreme1 , -broj_musterija_koje_customer_dovodi
FROM vip_restoran
UNION ALL
SELECT p_start_time AS vreme1, p_number
FROM DUAL
UNION ALL
SELECT p_end_time AS vreme1, -p_number
FROM DUAL
),
(
SELECT start_time AS vreme2
FROM vip_restoran
UNION ALL
SELECT end_time AS vreme2
FROM vip_restoran
UNION ALL
SELECT p_start_time AS vreme2
FROM DUAL
UNION ALL
SELECT p_end_time AS vreme2
FROM DUAL
)
WHERE vreme1<=vreme2
GROUP BY vreme2
)
Nazalost ovo resenje je dosta sporije od resenja koje se dobija koriscenjem analitickih funkcija. MS SQL 2005 podrzava SUM() OVER() sto je ANSI dodatak na sql-99 tako da steta sto ostale baze (osim ORACLE) to ne podrzavaju.
Standing ovations!!!
Potpis
"The best code is no code at all."
- Zidar (ES član)
"Biggest obstacle to learning
SQL is unlearning procedural
programming." - Joe
Celko
"Minimize code, maximize data."
- A. Neil Pappalardo
- Zidar (ES član)
"Biggest obstacle to learning
SQL is unlearning procedural
programming." - Joe
Celko
"Minimize code, maximize data."
- A. Neil Pappalardo
Dovoljno je bilo samo da se u google-u otkuca: sql running total. Prva 3 sajta nude resenje bez analitickih funkcija. Inace bio je jedan rad u kome je dokazano da analiticke funkcije ne omogucavaju nista novo i sve sto moze da se uradi sa analitickim funkcijama moze i bez njih. Analiticke funkcije samo olaksavaju i ubrzavaju i pisanje i izvrsavanje naredbi ali ne nude nista novo.