[ flashboy_didi @ 18.07.2009. 23:15 ] @
Pokusao sam da nadjem slicno pitanje ali nije mi uspjelo... unpred zahvaljujem na odgovoru


Zadatak 1.
Data je relacione baza podataka:

Prodavac(SifP, Naziv, Mesto)
Kupac(SifK, Naziv, Mesto)
Uređaj(SifU, Naziv)
Prodaja(SifP, SifK, SifU)



a) Sastaviti SQL upit koji daje nazive prodavaca koji su prodavali uređaje svim kupcima iz svog mjesta.
b) Sastaviti SQL upit koji daje nazive uređaje za koje je bilo prodaje, ali ne između prodavaca I kupaca iz istog mjesta.
c) Sastaviti upite relacione algebre, relacionog računa tprki I relacionog računa domena koji za prodaju daju nazive prodavaca I nazive kupaca


Zadatak 2.
Dati su šema relacije R koja je u 1NF i skup funkcijskih zavisnosti F:
R ( A, B, C, D, E, F ) F = { C->E , AB->D , DE->AB , B->C , E->F }
a) Odrediti sve kandidat-ključeve šeme R.
b) Ispitati redom da li je šema R u BCNF, 3NF i 2NF, uz navođenje u svakom koraku zavisnosti iz F koje su eventualno nesaglasne sa određenom normalnom formom.
c) Normalizovati šemu R u BCNF, uz navođenje kandidat-ključeva i skupa funkcijskih zavisnosti za svaku od nastalih šema, uključujući i međurezultate.
------------------------------------------------------------------------------------------------------------



je li može ovako da se reši?

Odgovor na zadatak 1.

a)
SELECT R1.Naziv FROM Prodavac R1, Kupac R2, Prodaja R3
WHERE NOT IN (R1.Mesto = R2.Mesto) AND (R3.SIFP = R1.SIFP)

ili

SELECT R1.Naziv FROM Prodavac R1, Kupac R2, Prodaja R3
WHERE NOT EXIST (R1.Mesto = R2.Mesto) AND (R3.SIFP = R1.SIFP)

b)

SELECT E1.Naziv FROM Uređaj E1, Prodavac R1, Kupac R2, Prodaja R3
WHERE E1.Naziv NOT IN (R1.Mesto = R2.Mesto) AND R3.SIFU = E1.SIFU

c) nisam siguran, pa ako može pomoć


za zadatak 2. nisam siguran da ga pocnem, bojim se da ne lupam neke gluposti


HVALA

[ Zidar @ 20.07.2009. 15:42 ] @
Lose ti se pise. Svi kveriji koje si napisao imaju veoma pogresnu sintaksu. Mozda je to dobro, jer imaju pogresnu i logiku. Kveri sa pogresnom logikom i dobrom sintaksom je opasan, jer ce da vrati pogresne podatke za koje poverujes da su dobri. Kveri sa losom sintaksom ne radi uopste, sto je bolje, jer bar ne dobijes pogresne podatke. kao ono "bolje biti glup nego krivo pametan"

Elem, NOT IN i EXISTS zahtevaju drugaciju sintaksu. To pronedji sam kako se radi.


Logika:
a) Sastaviti SQL upit koji daje nazive prodavaca koji su prodavali uređaje svim kupcima iz svog mjesta.

SELECT R1.Naziv FROM Prodavac R1, Kupac R2, Prodaja R3
WHERE NOT IN (R1.Mesto = R2.Mesto) AND (R3.SIFP = R1.SIFP)

ili

SELECT R1.Naziv FROM Prodavac R1, Kupac R2, Prodaja R3
WHERE NOT EXIST (R1.Mesto = R2.Mesto) AND (R3.SIFP = R1.SIFP)

Sto se tice logike, tvoj kveri (kad bi bio ispravne sintakse) u stvari bi odgovorio na pitanje: 'pokazi mi slucajeve gde su kupac i prodavaxc iz istog mesta'. To nije isto kao i 'pokazi mi prodavce koji su prodali robu ama bas svakom kupcu iz svog mesta'

Neka u mestu A postoji trgovac T1 i T2 i pet kupaca (k1,k2,k3,k4,k5). Trgovac T1 prodao je robu kopcima k1 i k2. Trgovac T2 prodao je robu kupcima (k1,k2,k3,k4,k5). Samo trgovac T2 zadovoljava pitanje a) - trgovac koji je savkom kupcu iz svog mesta prodao robu. Trgovac T1 je prodao robu samo dvojici od 5 mogucih kupaca, prema tome, on ne zadovoljava uslov zadatka. Odgovor se daje posmatranjem nekoliko kverija:

Q1: izaberi sve transakcije gde su kupac i trgovac iz uistog mesta:
(SELECT Trgovac, Kupac, mesto FROM kupci JOIN Trgovci ON kupci.mesto = trgovci.mest)
Ovo je u stvari upit koji si ti pokusao da napises.

Q2: prebroj koliko kupaca ima u svakom mestu
SELECt COUNT(*) AS brojKupacaUmestu FROM Kupci GROUP BY mesto => daje broj kupaca u datom mestu

Q3: prebroj koliko razlicitih kupaca iz svog mesta je opsluzio svaki trgovac
SELECT Trgovac, Mesto, COUNT(DISTINCT Kupac) AS BrojRazlicitihKupaca FROM Q1 GROUP BY Trgovac, Mesto

Q4: oni trgovci koji su opsluzili tacno onoliko kupca koilko ih ima u njihovom mestu su 'opsluzili sve kupce iz svog mesta'
SELECT Q3.Trgovac, Q3.Mesto, Q3.BrojRazlicitihKupaca , Q2.brojKupacaUmestu
FROM Q3 JOIN Q2 ON Trgovac.mesto = Q2.mesto
WHERE Q3.BrojRazlicitihKupaca = Q2.brojKupacaUmestu

To ti je logika. Moze li da se napise u jednom kveriju? Moze, to se zove 'relaciono deljenje' i sigurnmno ima objasnjeno u knjizi koju koristis za ispit.


b) Sastaviti SQL upit koji daje nazive uređaje za koje je bilo prodaje, ali ne između prodavaca i kupaca iz istog mjesta.

Ovde ti je logika OK, pokusavas da kazes upravo to "gde kupac i trgovac nisu iz istog mesta' Samo jos da pogodis sintaksu (JOIN, pa WHERE, NOT IN ili EXIST ti uopste ne treba). Ovaj zadatak je mnogo laksi nego ono pod a) i trebalo bi da znas da ga resis.


SELECT E1.Naziv FROM Uređaj E1, Prodavac R1, Kupac R2, Prodaja R3
WHERE E1.Naziv NOT IN (R1.Mesto = R2.Mesto) AND R3.SIFU = E1.SIFU


Za ostalo, ne znam, ja samo pisem kverije kad zatreba, za ostalo treba neko skolovan po propisu

:-)
[ captPicard @ 20.07.2009. 16:34 ] @
Lijepo objašnjeno, svaka čast :-)

Ali mislim da si pod a) krivo shvatio. Pitanje je da se nabroje svi prodavači koji su prodavali SVIM kupcima iz svog mjesta.
[ flashboy_didi @ 20.07.2009. 17:19 ] @
@Zidar
hvala na bas detaljnom objasnjenju, a uvjek sam se drzao toga "bolje priznati da si glup nego da nisi pametan" (dodje kao isto, ali nije)

mada sta mi onda fali pod a) jel mogu da dodam jos jedan uslov (R3.SIFK = R2.SIFK), jbg ovo sve napamet radim ... mozda bi trebalo da instaliram neki editor za SQL (mysql front) pa to sve fino testirati

hvala jos jednom
[ Zidar @ 20.07.2009. 19:55 ] @
@ captPickard "Ali mislim da si pod a) krivo shvatio. Pitanje je da se nabroje svi prodavači koji su prodavali SVIM kupcima iz svog mjesta. " bas tako sam shvatio. Vidi ovo:
Citat:
Neka u mestu A postoji trgovac T1 i T2 i pet kupaca (k1,k2,k3,k4,k5). Trgovac T1 prodao je robu kopcima k1 i k2. Trgovac T2 prodao je robu kupcima (k1,k2,k3,k4,k5). Samo trgovac T2 zadovoljava pitanje a) - trgovac koji je savkom kupcu iz svog mesta prodao robu. Trgovac T1 je prodao robu samo dvojici od 5 mogucih kupaca, prema tome, on ne zadovoljava uslov zadatka.


@ flashboy_didi uvek je bolje na nzati nego krivo znati, u pravu si generalno :-) Ko ne zna i zna da ne zna, on nece napraviti nista dobro (jer ne zna) ali nece ni pokvariti sta ima (jer zan da ne zna). Ko ne zna da ne zna, pokvarice i sta iam :-)

Kveri ne mozes popraviti prosirenejm dodavanjem (R3.SIFK = R2.SIFK), u postojeci WHERE. Rekoh, u pitanju ej relaciona divizija, deljenje i resava se tako sto s euporedjuej broj kupaca u datom mestu sa brojem kupaca iz tog istog mesta koje je opsluzio posmatrani trgovac

Ovo je kvari u MS SQL sintaksi, ali mislim da ce proci na bilo kom drugom sitemu. Shvatam da ti koristis MySQL, ali ako znas 'standardni' SQL moci ces da razumes sta sam napisao:
Code:

SELECT
-- izbroj koliko kupaca je obsluzio prodavac SifP 
PR.SifP,  COUNT(DISTINCT PR.SifK)        
FROM Prodaja AS PR
JOIN prodavac AS P2 ON P2.SifP = PR.SifP 
JOIN Kupac AS K ON K.SifK = PR.SifK
-- pri tome broj samo one prodaje gde su kupac i prodavac iz istog mesta
WHERE K.mesto = P2.mesto
GROUP BY PR.SifP
-- i gde je broj opsluzenih kupaca jednak broju kupaca iz datog mesta
HAVING COUNT(DISTINCT PR.SifK) = (SELECT COUNT(*) 
                                    FROM Kupac AS K2
                                    WHERE K2.Mesto = P2.mesto)

[ flashboy_didi @ 20.07.2009. 20:24 ] @
Hvala jos jednom. Ipak sam odlucio da instaliram neki browser/editor SQL. Nije mi sada bitno koji, samo da skontam pravo znacenje sintakse. Sada sam skontao na sta si mislio kada si rekao da mi treba JOIN, ne mogu nista raditi dok ne pridruzim sve te tabele.


Hvala puno. Nadam se da ce biti odgovora i za 2gi zadatak. :)