[ sojic @ 13.07.2007. 10:56 ] @
Imam sledecu tabelu:

Code:

id, mesec, pretplatnik, iznos, placeno
1, 2007-01-01, 1, 500, "2007-03-20"
2, 2007-02-01, 1, 500, ""
3, 2007-03-01, 1, 500, ""
4, 2007-04-01, 1, 500, ""
5, 2007-05-01, 1, 500, ""


Znaci, jedan pretplatnik ima mesecne racune. (mesec dobijem = month(mesec)). Ako je racun placen u polje "placeno" imam datum placanja.

Kako kada stampam racun da prikazem i "neplacene" racune. Znaci, stampam racun za mesec 5, a tamo negde da dobijem:

Mesec: 5
Iznos: 500
Zaostale mesece: 2,3,4
Zaostali iznos: 1500

[ Zidar @ 13.07.2007. 14:00 ] @
Prosto. Nadjes Access programera i on ti napravi report kakav hoces :-)

Salu na stranu, kveriji ne sluze za pravljenje i stampanje formatiranih izvestaja. Format koji zahtevas,
Citat:

Mesec: 5
Iznos: 500
Zaostale mesece: 2,3,4
Zaostali iznos: 1500

veoma je tezak za bilo koji dijalekt SQL-a.
Problem je u delu
Citat:
Zaostale mesece: 2,3,4

Naravno da moze da se uradi, ali zavisi od konkretnog sistema koji upotrebljavas. ORACLE to radi na jedan nacin, MS SQL na drugi, Firbird na treci, MySQL na cetvrti i tako dalje. Neki nacini su laksi, neki tezi. I kad sve to napravis, report ne izgleda lepo kao sto izgleda kad ga napravis u nekom od alata koji su namenjeni za pravljenje reporta.

Jesi li jos uvek siguran da zelis da pravis report kverijem? Ako jesi, kazi koju bazu koristis pa ce ti neko vec dati konkretan odgovor.

:-)

[ sojic @ 17.07.2007. 10:53 ] @
Znaci, ne stampam report preko SQL, vec rec mi je bio da "generisem sadrzaj za report".

Radi se o MySQL bazi.

Da ne komplikujemo, zaostale mesece nije bitno (trenutno), bitan je zaostali iznos.

Znaci....

Svaki mesec zaduzujem pretplatnika, svaki mesec stampa racun za odredjeni mesec, a zaostali dug je suma od neplacenih prethodnih meseca.
[ chachka @ 17.07.2007. 11:56 ] @
Nesmem da dam kompletno resenje posle onakvih uvodnih recenica Zidara :)

Zato cu pokusati da ti pomognem da sam dodjes do resenja. Kako ces prikazati poslednji mesec u kom je jednom korisniku izdat racun?

SELECT MAX(...) FROM ... WHERE ...?
[ sojic @ 17.07.2007. 12:14 ] @
Nije mi problem poslednji mesec (koristim WHERE),

Problem mi je kako da izvrsim dve query-ja u jedno.

Znaci.
Code:

SELECT iznos FROM placanja WHERE month(mesec)=5
select sum(iznos) az zaostalo from placanja where month(mesec)<5 and platenoDatum is null group by pretplatnik

Ovo mi treba u jedno query (ako je moguce).
[ chachka @ 17.07.2007. 13:43 ] @
Napravis u oba upita po dve kolone pazeci da su istog tipa. Nepotrebnu kolonu popunis nulom.
Code:

SELECT iznos, 0.00 AS zaostalo FROM placanja WHERE month(mesec)=5

select 0.00 AS iznos, sum(iznos) az zaostalo from placanja where month(mesec)<5 and platenoDatum is null group by pretplatnik

sada ova dva upita spojis sa unijom
Code:

SELECT iznos, 0.00 AS zaostalo FROM placanja WHERE month(mesec)=5
 UNION ALL
select 0.00 AS iznos, sum(iznos) az zaostalo from placanja where month(mesec)<5 and platenoDatum is null group by pretplatnik

i na kraju uzmes maksimum obe vrednosti
Code:

SELECT MAX(u.iznos), MAX(u.zaostalo)
  FROM (SELECT iznos, 0.00 AS zaostalo FROM placanja WHERE month(mesec)=5
         UNION ALL
        select 0.00 AS iznos, sum(iznos) az zaostalo from placanja where month(mesec)<5 and platenoDatum is null group by pretplatnik
       ) AS u

To je zavrsetak puta kojim si ti krenuo, a postoje i drugaciji putevi.
[ sojic @ 17.07.2007. 14:01 ] @
Danke bitte, korisan odgovor.

Nisam pokusao, ali to je to.
[ sojic @ 18.07.2007. 14:13 ] @
Da, query je OK, ali sad imam drugi problem.

Problem je sto pored ovo query ja imam drugo "osnovno" koje selektuje * pretplatnike i onda radim join za matematiku, ali....

Hteo sam ovaj query da stavim u view pa da radim join na view.

Evo moj query (koj radi bez "zaostali" iznos)

Code:

select `vshowpretplatnici`.`Id` AS `id`,`vshowpretplatnici`.`ime` AS `ime`,`vshowpretplatnici`.`prezime` AS `prezime`,`vshowpretplatnici`.`imeUlica` AS `imeUlica`,`vshowpretplatnici`.`broj` AS `broj`,`placanja`.`iznos` AS `iznos`,month(`placanja`.`mesec`) AS `mesec`,year(`placanja`.`mesec`) AS `godina`,`placanja`.`tip` AS `tip` from (`vshowpretplatnici` join `placanja` on ((`vshowpretplatnici`.`Id` = `placanja`.`pretplatnik`)))


E sad.... placanja je tabela.

Ideja mi je bila da kreiram view i da umesto tabelu koristim view, ali.... ne mogu kreirati view zato sto query sadrzi subquery, union bla bla bla.

Kako da iskombinujem join sa query koje sadrzi union?
[ chachka @ 19.07.2007. 08:46 ] @
Ipak nismo na kraju tvog puta :)

Ako sam dobro shvatio hoces da povezes podatke o dugovanju s podacima o pretplatnicima.

Ne mozes da koristis VIEW tako kako si zamislio jer si fiksirao mesec na 5. Kada bi hteo podatke o 6-tom mesecu morao bi da menjas VIEW.

Zato sam i krenuo od upita kojim se dolazi do poslednjeg meseca za koji postoji racun, ali je i tip podataka za cuvanje 'meseca' nezgrapan. Da li moze da ti se desi da se jednom pretplatniku izda racun pod '2007-05-01', a drugom pod '2007-05-02'?

PS: Zasto se tabela zove 'placanja' kada se u njoj nalaze podaci o racunima? Zbunjujuce je. Pravilno imenovanje je bitno u modeliranju realnih sistema. Bez toga bi tvoj predhodni upit mogao da se napise i kao:
Code:

SELECT a.a,a.b,a.c,a.d,a.e,b.a, month(b.b) AS z, year(b.b) AS y, b.c
  FROM a INNER JOIN b ON a.a = b.d
Ko bi se mogao snaci na osnovu toga?
[ sojic @ 19.07.2007. 11:45 ] @
OK, tabela "placanja" bi trebalo da se zove "racuni", ali jos uvek postoi problem kako da "povezem" tabelu "pretplatnike" sa "???? (query, view, stored procedure, whatever)".
[ chachka @ 19.07.2007. 12:09 ] @
To je bio PS.

Ocekivao sam odgovor na:
Citat:
Da li moze da ti se desi da se jednom pretplatniku izda racun pod '2007-05-01', a drugom pod '2007-05-02'?
[ Zidar @ 19.07.2007. 14:19 ] @
meni se cini da ovde imamo posla sa fiksnim mesecnim uplatnicama. Za svaki mesec, izda se jedna uplatnica. Ona se ili plati ili ne plati. Proizilazi da se moze platiti samo onoliki iznos koliki je na uplatnici, ni vise ni manje. Samo tako ima smisla polje 'Placen', sa znacenjem 'datum kad je ova uplatnica placena'. Ako je NULL, znaci da doticna uplatnica nije placena.

To zakljucujem iz primara tabele koji je dat u pocetnom postu:

Code:

id, mesec, pretplatnik, iznos, placeno
1, 2007-01-01, 1, 500, "2007-03-20"
2, 2007-02-01, 1, 500, ""
3, 2007-03-01, 1, 500, ""
4, 2007-04-01, 1, 500, ""
5, 2007-05-01, 1, 500, ""


i objasnjenja iz drugog posta
Citat:

Svaki mesec zaduzujem pretplatnika, svaki mesec stampa racun za odredjeni mesec, a zaostali dug je suma od neplacenih prethodnih meseca.


Ako govorimo o palcenim uplatnicama (Racunima), sve sto mozemo da uradimo jeste da za dati mesec prebrojimo koliko je bilo uplatnica (zaduzenja) zakljucno sa tim mesecom, i koliko njih je placeno ili nije placeno. Datum placanja izgleda potpuno nebitan, jer mi se cini da se uplatnice mogu placati bilo kojim redom. Na primer:

Code:

id, mesec, pretplatnik, iznos, placeno
1, 2007-01-01, 1, 500, "2007-03-20"
2, 2007-02-01, 1, 500, "2007-02-15"
3, 2007-03-01, 1, 500, "2007-03-20"
4, 2007-04-01, 1, 500, ""
5, 2007-05-01, 1, 500, ""


Ovde se vidi da pretplatnik nije platio januarsku uplatnicu na vreme, pa je februarsku platio 15 Feb, a onda je u martu platio i martovsku i januarsku istog dana, 20 marta. Ovo ne bi trebalo da bude nemoguce, zar ne?

Predlazem kveri koji prikazuje kumulativno zaduzenje zakljucno sa mesecom i kumulativni broj (COUNT) placenih uplatnica koje su izdate zakljucno sa mesecom. Nesto ovako:

Code:

SELECT
Pretplatnik
, BrojIzadtihRacuna = (SELECT COUNT(*) FROM Pretplata AS B WHERE WHERE B.Mesec <= A.Mesec )
, KumulativnoZaduzenje = (SELECT SUM(Iznos) FROM Pretplata AS B WHERE B.Mesec <= A.Mesec)
, BrojPlacenihRacuna = (SELECT COUNT(*) FROM Pretplata AS B WHERE WHERE B.Mesec <= A.Mesec 
                           AND  B.Placeno IS NOT NULL)
, KumulativnoPlaceno = (SELECT SUM(Iznos) FROM Pretplata AS B WHERE WHERE B.Mesec <= A.Mesec 
                           AND  B.Placeno IS NOT NULL)

, BrojNeplacenih = (SELECT COUNT(*) FROM Pretplata AS B WHERE WHERE B.Mesec <= A.Mesec 
                           AND  B.Placeno IS NULL)
, IZnosDuga = (SELECT SUM(Iznos)  FROM Pretplata AS B WHERE WHERE B.Mesec <= A.Mesec 
                           AND  B.Placeno IS NULL)
FROM Pretplata AS A
GROUP BY Pretplatnik


Ovaj kveri daje lepu sliku u nekom zadatom trenutku. I nema mesec u WHERE, pa se moze koristiti kao view koji ce biti osnova za report (SELCt * FROM view WHERE mesec=...)

Ako se zeli prikazatii vise podataka o korisniku, a ne samo ID, onda probaj dodati JOIN, otprilike ovako:
Code:

SELECT
Pretplatnik
, Ime = MAX(P.ImePretplatnika)
, Prezime = MAX(P.Prezimepretplatnika)
, Adresa = MAX(P.Adresa)
, BrojIzadtihRacuna = (SELECT COUNT(*) FROM Pretplata AS B WHERE WHERE B.Mesec <= A.Mesec )
, KumulativnoZaduzenje = (SELECT SUM(Iznos) FROM Pretplata AS B WHERE B.Mesec <= A.Mesec)
, BrojPlacenihRacuna = (SELECT COUNT(*) FROM Pretplata AS B WHERE WHERE B.Mesec <= A.Mesec 
                           AND  B.Placeno IS NOT NULL)
, KumulativnoPlaceno = (SELECT SUM(Iznos) FROM Pretplata AS B WHERE WHERE B.Mesec <= A.Mesec 
                           AND  B.Placeno IS NOT NULL)

, BrojNeplacenih = (SELECT COUNT(*) FROM Pretplata AS B WHERE WHERE B.Mesec <= A.Mesec 
                           AND  B.Placeno IS NULL)
, IZnosDuga = (SELECT SUM(Iznos)  FROM Pretplata AS B WHERE WHERE B.Mesec <= A.Mesec 
                           AND  B.Placeno IS NULL)
FROM Pretplata AS A
JOIN Pretplatnici AS P ON P.Pretplatnik = A.pretplatnik
GROUP BY Pretplatnik


MAX je upotrebljeno da ne bi morali u GROUP BY da ubacimo Ime, prezime i Adresu

Medjutim, meni je cela logika klimava. Ako korisnik izgubi uplatnicu, kako ce da plati? Zasto se ne moze uplatiti iznos razlict od onoga koji je na racunu? Placam koliko mogu i kad mogu? Posto je logika klimava, stalno imas probleme sa sastavljanjem dobrog kverija koji prikazuje sta se u stvari desilo. Losa logika => los dizajn baze => tesko se izvlace podaci (tesko se i unose)

:-)