[ YuMERA @ 27.12.2013. 22:39 ] @
Imam dve tabele tblArtikli i tblRacuni i trebam da napravim jedan izvestaj koji ce prikazati artikle koji nisu prodavani ni jednom...

Query koji glasi:
Code:
SELECT aNaziv,aSifra,aPorez,aMera FROM tblArtikli,tblRacuni WHERE  aSifra = rStavka GROUP BY aNaziv


vraca artikle koji su prodavani meni treba query koji ce mi napraviti recordset sa artiklima koji nisu ni jednom prodavani...

aSifra iz tblArtikli vidljiva je u tblRacuni kao rStavka..

poz i hvala...
[ Jbyn4e @ 28.12.2013. 07:32 ] @
Možda nešto kao....
Code:

SELECT aNaziv,aSifra,aPorez,aMera FROM tblArtikli WHERE  aSifra NOT IN (SELECT rStavka FROM tblRacuni) GROUP BY aNaziv
[ YuMERA @ 28.12.2013. 09:12 ] @
Hvala.. to je to...

A evo ovako sam napravio da se taj record set kreira i udredjenom vremenskom periodu...
Code:
SELECT aNaziv,aSifra,aPorez,aMera,rDatum FROM tblArtikli,tblRacuni WHERE aSifra NOT IN (SELECT  rStavka FROM tblRacuni ) AND rDatum BETWEEN '2013-12-20' AND '2013-12-28' GROUP BY aNaziv


....
Hvala jos jednom

[Ovu poruku je menjao YuMERA dana 28.12.2013. u 11:09 GMT+1]
[ bogdan.kecman @ 29.12.2013. 14:20 ] @
racunaj da je to uzasno spor query kako god da ga napravis .. vrlo cesto se, kada ima ceste potrebe za vadjenjem "ne prodavanih", pravi zasebna tabela koja je "product_id, prodavan", na glavnom tabeli imas triger koji kada god imas insert u nju insertuje i slog u tu zasebnu tabelu, a svaki put kada kreiras racun uradis za svaki artikl u zasebnoj tabeli prodavan+1 tako dobijes lako select * from zasebnatabela where prodavan=0 sve koji nisu prodavani nikad a mozes i da vadis koji su najvise prodavani i slicno
[ Jbyn4e @ 29.12.2013. 18:17 ] @
Da, ovo deluje kao mnogo bolje rešenje nego da zavisiš od brzine pronalaženja svih iz tabele računa, pa da tražiš iz druge tabele one koji nisu u toj tabeli. (ala sam ga objasnio)...

Hvala Bogdanu...
[ bjevta @ 30.12.2013. 08:53 ] @
moglo bi sa onim select-om, samo bih predlozio left join umesto subselect-a. ako subselect vraca malo podataka, onda je ok ali ako vraca vise, mislim da to za MySQL nije optimalan upit (bogdane, ispravi me ako gresim).

ja bih stavio: SELECT aNaziv,aSifra,aPorez,aMera,rDatum FROM tblArtikli LEFT JOIN tblRacuni ON ... WHERE tblRacuni.aSifra IS NULL

alternativno, moze da se ubaci COUNT pa da se dobije koji artikal je koliko puta prodavan. u tom slucaju ne treba WHERE tblRacuni.aSifra IS NULL vec nesto tipa:

SELECT aNaziv,aSifra,aPorez,aMera,rDatum, COUNT(tblRacuni.aSifra) as BrojProdaja FROM tblArtikli LEFT JOIN tblRacuni ON ... GROUP BY aNaziv,aSifra,aPorez,aMera,rDatum ORDER BY COUNT(tblRacuni.aSifra) ASC (ili DESC, ako trazis najprodavanije artikle)

inace ne podrzavam praksu keshiranja business podataka tipa proste agregacije iz child tabele u master tabeli, osim ako za to ne postoji debeo razlog a ovde ga ne vidim. ako artikala ima puno (100-ne hiljada) onda bi mozda imalo smisla ali ne zbog ovog izvestaja koji se, cenim, generise jednom mesecno ili kvartalno.

ako se resis da drzis broj prodaja u tabeli artikala, predlazem da se ona azurira stored procedurom, ne iz koda - integritet podataka ove vrste je stvar baze, ne aplikacije.
[ bogdan.kecman @ 30.12.2013. 09:10 ] @
Citat:
bjevta: moglo bi sa onim select-om, samo bih predlozio left join umesto subselect-a. ako subselect vraca malo podataka, onda je ok ali ako vraca vise, mislim da to za MySQL nije optimalan upit (bogdane, ispravi me ako gresim).


na zalost za mysql ne postoji optimalan upit koji ce iz tabele T1 da prikaze one koji ne postoje u T2. To ce uvek biti full table scan, samo pitanje dal ce se pomnoziti sa drugom tabelom ili ne.
kada se resava taj problem uvek se postavlja pitanje "za koji ti djavo to treba" i "koliko ce to cesto da se tera" .. ako takav upit ide jednom godisnje ili mozda jednom u tromesecju, nacukas ga "kako god" i pustis na slave-u pa ako trci cuku ili dan nije bitno, ako pak takav upit treba da trci dnevno onda je jedino resenje materijalizacija te date uz trigere i procedure.

Citat:
bjevta:
alternativno, moze da se ubaci COUNT pa da se dobije koji artikal je koliko puta prodavan.

isto extremno sporo posto moras da pomnozis dve tabele i onda radis sortiranje preko toga (ili having ako hoces samo jednu vrednost), generalno sporije dosta od "daj mi samo one koji nisu"

Citat:
bjevta:
inace ne podrzavam praksu keshiranja business podataka tipa proste agregacije iz child tabele u master tabeli, osim ako za to ne postoji debeo razlog a ovde ga ne vidim. ako artikala ima puno (100-ne hiljada) onda bi mozda imalo smisla ali ne zbog ovog izvestaja koji se, cenim, generise jednom mesecno ili kvartalno.

ako se resis da drzis broj prodaja u tabeli artikala, predlazem da se ona azurira stored procedurom, ne iz koda - integritet podataka ove vrste je stvar baze, ne aplikacije.


kao sto rekoh, za resenje je vrlo bitno "za koji djavo se ovo koristi" .. ako je za godisnji izvestaj na kraju godine nije isto kao za dnevni izvestaj .. a sto se materijalizacije tice, da, uvek i samo uz pomoc trigera i procedura, nikako iz aplikacije
[ bjevta @ 30.12.2013. 09:31 ] @
ono za COUNT sam nabacio vise kao primer da bi, kad vec rola neki upit, dobio odjednom sve potrebne informacije.

YuMERA, kad krenu takvi izvestaji tipa koliko/sta, verovatno ce ti trebati i neka statistika prodaje, recimo po periodima (mesec, kvartal, godina) te ce taj tblRacun morati da ima i datum prodaje, pa da se uzme GROUP BY aSifra, MONTH(datum_prodaje), itd.. Onda ce trebati jos indexa, mozda neka particija, itd, itd.

[ farmaceut @ 30.12.2013. 09:52 ] @
Koliko redova u tblRacuni, kakav hardver i koliko0 se to cesto koristi?
Mozda bi trebao uvesti tabelu "stanja" u kojoj ces voditi sifru artikla, kolicinu ulaza, kolicinu izlaza, stanje.
Updatovati je kod svake transakcije.
Obicno u takvim aplikacijama cesto imas potrebu za trenutnim stanjem, pa tabela "stanja" itekako ima smisla, pogotovo kod velikog broja transakcija.
Tu onda prilicno "jeftino" vidis sta nije izlazilo.
[ YuMERA @ 05.01.2014. 01:13 ] @
Hvala svima na pomoci. Shvatio sam a i isprobao i uvideo da je poprilicno spor queri ali taj izvestaj ce trebati mozda samo nekoliko puta po potrebi. Inace radi se o relativno maloj bazi artikala (ok 200) i testirao sam queryi na tblRacuni koja ima oko 1950 recorda i izmereno vrema kreiranja izvestaja za upit je oko 2100ms e sad kad bude veca tblRacuni vreme ce biti sigurno vece ali neznamo kojom proporcijom... Ako bude cesce potrebe da se posmatra ta "ne prodaja" artikala onda cu verovatno po Bogdanovoj preporuci praviti zasebnu tabelu u kojoj cu to pratiti...
Svi artikli su prodani bar jednom ali treba taj izvestaj da vidi dali ima ne prodavani artikala za odredjeni period koji moze biti proizvoljan

poz...
YuMERA
[ bjevta @ 05.01.2014. 04:17 ] @
2100 ms mi zvuči jaaako puno, toliko puno da mislim da ima neki zez. ako hoćeš, upit koji si napravio i attachuj zipovan db dump, raspoložen sam da pogledam. ako ne, udri EXPLAIN SELECT <ostatak upita> pa nabači sql output, da pogledamo
[ YuMERA @ 05.01.2014. 20:57 ] @
Sorry, moja greska... vreme sam merio u mojoj aplikaciji ali sam merenje zavrsavao kad mi se popuni i listView tako da direktan upit u MySQL traje manje od 900ms... izvinjavam se jos jednom... da vas vise ne opterecujem ovom temom jer ovaj upit mi nece praviti tolike probleme posto nece biti cesto potrebe za njim...
[ YuMERA @ 05.01.2014. 21:42 ] @
Moram da se javim jos jednom povodom ovoga... posto procitah ovo : Hvala Bogdanu stavih ja index na rStavku u tblRacuni i MySQL uradi to za 10 ms... e sad nije da sam mislio da ne treba index nego sam previdio da ga stavim. Do sad sam aplikacije koje trebaju bazu radio sa MDB bazom pa sad mi MySQL malo "stran" dok se ne "naviknem"....