[ NenadS @ 17.07.2007. 15:39 ] @
Pokusavam da resim ovaj problem tako sto cu upotrebiti sto manje sql upita ali za sada nisam nasao adekvatno resenje, pa mi je potrebna vasa pomoc...

Tabela 1:

Code:
U_ID - KREDIT
1 - 3
2 - 1
3 - 0
4 - 2


Tabela 2:

Code:
P_ID - U_ID
1 - 1
2 - 1
3 - 1
4 - 1
5 - 2
6 - 2
7 - 3
8 - 4


O cemu se radi... iz prve tabele trebam za svaki U_ID da proverim koliko kredita ima, a zatim da iz druge tabele za svaki U_ID iz prve uzmem onoliko P_ID koliko kredita svaki U_ID ima... i da to bude odradjeno sa sto manje upita...

Znaci rezultat bi u ovom slucaju bio sledeci:

Za U_ID 1 imao bih P_ID 1, 2 i 3, za U_ID 2 imao bih P_ID 5, za U_ID 3 nema rezultata i za U_ID 4 imao bih P_ID 8.

Sto znaci da ako imam vise podataka u drugoj tabeli nego kredita za taj U_ID u prvoj onda uzima samo onoliko koliko kredita ima... ili ako imam manje nego kredita, onda uzima ono sta ima... ako je kredit 3, a u drugoj tabeli imam 2 upisa, onda ce uzeti ta 2...

Ono kako ja to znam da uradim, a sto mi se ne svidja jeste da preko prvog upita uzmem vrednosti U_ID i P_ID, a zatim da kroz petlju dok ima rezultata ponavljam drugi sql upit koji ce da uzima onoliko vrednosti iz druge sa LIMIT koliko ima kredita gde je U_ID prve = U_ID druge tabele...

To nije problem ako u prvoj tabeli imam 4-5 upisa... to su 5 ili 6 sql upita... ali je problem ako imam 200 ili 1000, onda je to 201 ili 1001 upit... a to je vec mnogo... pa me zanima da li to moze drugacije da se napise, a da dobijem ovo sto mi je potrebno?

Drugi nacin jeste da preko jednog upita selektujem U_ID i broj kredita, a onda da preko drugog pokum SVE sto je u drugoj tabeli i onda da uzmem samo onoliko koliko mi treba... sto opet ne valja ako u drugoj tabel imam par desetina hiljada upisa...

Hvala unapred

[Ovu poruku je menjao NenadS dana 17.07.2007. u 17:34 GMT+1]
[ chachka @ 17.07.2007. 20:29 ] @
Spoj tabelu 2 samu sa sobom i numerisi svaki P_ID u okviru U_ID-a da numeracija krece od 1. Tada ovaj rezultat spoj sa tabelom 1 i prikazi one P_ID-ove cija je numeracija manja ili jednaka kreditu odredjenog U_ID-a.
[ NenadS @ 17.07.2007. 20:42 ] @
Nisam bas siguran da mi je jasno ovo sto si napisao ali ako bi mogao da napises jedan tj. ta dva ili koliko vec upita, to bi bilo super.
[ chachka @ 17.07.2007. 21:40 ] @
Code:

SELECT sj.u_id, sj.p_id
  FROM (SELECT t21.u_id, t21.p_id, COUNT(t22.*) AS redni_broj
          FROM tabela_2 AS t21
               INNER JOIN
               tabela_2 AS t22
                 ON t21.u_id = t22.u_id
                AND t21.p_id >= t22.p_id
         GROUP BY t21.u_id, t21.p_id
       ) AS sj
       INNER JOIN
       tabela_1 AS t1
         ON t1.u_id = sj.u_id
 WHERE t1.u_id = sj.u_id
   AND t1.kredit >= sj.redni_broj
 ORDER BY sj.u_id, sj.p_id
[ NenadS @ 17.07.2007. 22:26 ] @
Ovo daje tacan rezultat ali morao sam da ispravim COUNT(t22.*) u COUNT(t22.u_id) ali... upit se za 4 usera i 2500 poruka u drugoj bazi izvrsava za 15 sekundi... sto je bas bas mnogo... i za to vreme naravno sve se spuca :( moze li to nekako da se sredi da se ne izvrsava toliko dugo?

Hvala u svakom slucaju na pomoci :)
[ Tyler Durden @ 18.07.2007. 08:48 ] @
Mislim da što se tiče dužine izvršavanja samog upita nećeš moći ništa da uradiš. Možda neke optimizacije na samom serveru, ali to ti neće mnogo pomoći.
[ chachka @ 18.07.2007. 18:03 ] @
Prebrojavanje clanova tabele na opisan nacin (inner join, count, >= uz group by) jeste zahtevna operacija. Radi se o algoritmu slozenosti n^2 (kao dvostruka for petlja). Takve upite najcesce ne pustam cele vec obavezno sa dodatnim where klauzulama. Kada i pustam cele upite to su obicno servisne stvari ili upiti koji nisu kriticni po pitanju brzine odziva.

Upit se moze ubrzati ako se izbegne njegov najsporiji deo, a to je da se izbegne prebrojavanje.

Postoji mogucnost za drasticnim ubrzanjem ali to zahteva da su ti p_id-ovi bez rupa to jest da je COUNT(p_id) = MAX(p_id) - MIN(p_id) + 1. Da li je to kod tebe slucaj?
[ NenadS @ 18.07.2007. 20:22 ] @
U mom slucaju nije tako... ali posle 3 dana zezanja doslo je do toga da to sto pisem nije dobro resenje... nego treba drugacije... pa sam odradio na drugi nacin koji je dosta jednostavniji i za sada je sve u redu.

Hvala na pomoci, ovo ce mi mozda zatrebati u nekoj drugoj situaciji :)