[ RoNET @ 11.03.2008. 02:28 ] @
Pozdrav, Imam tabelu sa nekih 150 000 upisa, pa zbog nekih statistickih uzoraka bi mi trebao svaki 50 zapis u tabeli, da li je to moguce preko upita da se odradi ili to treba isprogramirat? |
[ RoNET @ 11.03.2008. 02:28 ] @
[ Getsbi @ 11.03.2008. 07:06 ] @
Izgeneriši novu tabelu sa 3000 zapisa (150000/50=3000). To uradi u For....Next petlji sa korakom 50. Naknadno stavi ovu novu tabelu u SQL iskaz sa tvojom postojećom koristeći LEFT JOIN. To bi trebalo da ti reši problem.
Mada mislim da je korišćenje RND() funkcije (koja daje slučajan broj) mnogo bolje za kvalitetan statistički uzorak. [ domaci_a_nas @ 11.03.2008. 08:36 ] @
Mislim da imam najkraće rešenje za tvoj problem. U pravu je Getsbi da treba da se generiše nova tabela, ali mislim da je broj recorda preveliki da bi se koristila For Next petlja. Da bi rešenje bilo efikasno, ali kompletno, postaviću ovde kod koji proverava da li pre kreiranja nove tabele već postoji tabela sa tim nazivom, u tom slučaju bi se pojavila greška. Samo da napomenem da koristim DAO.
Code: ' Ide u modul Public Sub DIET(WhName As String) If ObjExist(WhName, 1) Then DoCmd.DeleteObject acTable, WhName End Sub Public Function ObjExist(ObjName As String, ObjType As Long) As Boolean ObjExist = DCount("Name", "MSysObjects", "Name = '" & ObjName & "' And Type = " & ObjType) > 0 End Function Public Sub DelFi(WhTab As String, FiNam As String) On Error Resume Next CurrentDb.TableDefs(WhTab).Fields.Delete (FiNam) End Sub Recimo da ti se Tabela sa 150 000 podataka zove Tabela1, a ta nova Tabela TempTabela. Na formi recimo imaš dugme NovaTabela koje treba da generiše novu tabelu. Code: Private Sub NovaTabela_Click() DIET "TempTabela" StrSQL = "SELECT Tabela1.* INTO TempTabela FROM Tabela1 ORDER BY Tabela1.ID;" CurrentDb.Execute StrSQL DelFi "TempTabela", "ID" StrSQL = "ALTER TABLE NovaTabela ADD ID AUTOINCREMENT PRIMARY KEY" CurrentProject.Connection.Execute StrSQL StrSQL = "DELETE TempTabela.* FROM TempTabela WHERE ((([ID] Mod 50)<>1));" CurrentDb.Execute StrSQL End Sub Eto, da malo prođem kroz kod, u principu, prvo briše TempTabelu ako postoji, zatim je generiše. Možda primarni ključ iz Tabele1 nije sekvencijalan (možda je tokom vremena bilo i brisanja podataka pa ide 1, 2, 4...), pa to polje brišemo i generišemo nov primarni ključ. U poslednjoj liniji ostavljamo samo recorde sa rednim brojem 1, 51, 101... Pozdrav svima [ Getsbi @ 11.03.2008. 11:11 ] @
Možda nije najelegantnije ali nije ni sporo. Tabelu od 3000 slogova računar mi izgeneriše za manje od 3 sec.
![]() Ovaj moj računar i nije neki. Celeron(R) CPU 2.6 GHz. No sve jedno. Važno je da RoNET ima rešenje. [ RoNET @ 11.03.2008. 12:37 ] @
Hvala vam, i mislio sam ovako nesto ali eto htio sam da vidim sta i ostali misle.
A sto se tice statistickog uzorka znam da je najbolje rjesenje pomocu random funkcije ali meni je trebala bas ovakva metoda da mi da svaki 50-ti Uglavnom probacu ovo kasnije pa cu vam prenijet kako funkcionise :) [ Zidar @ 11.03.2008. 12:57 ] @
Citat: A sto se tice statistickog uzorka znam da je najbolje rjesenje pomocu random funkcije ali meni je trebala bas ovakva metoda da mi da svaki 50-ti Ako se govori o svakom pedesetom rekordu u tabeli, onda se podrazumeva da je tabela nekako sortirana. Samo u tom slucaju ima smisla govoriti o n-tom rekordu. Da se ne bi brljalo po dizajnu postojece tabele, mozes da napravis pomocnu tabelu koja ima PK kolone iz originalne tabele, plus autonumber kolonu. Onda originalnu tabelu sortiras kako zelis u kveriju i to APPEND u pomocnu tabelu. Onda na pomocnoj tabeli odradis SELECT * FROM TempTabela WHERE [ID] Mod 50=1 i dobijes svaki pedeseti rekord. Eto tvog uzorka. Izvuden je svaki 1, 51, 101, 151... itd. rekord. Ako originalna tabela vec ima [ID] koji ide od 1 do N, bez praznina, onda naravno ne treba pomocna tabela. Cenim trud koji bi domaci_a_nas ulozio da dodje do resenja,ali mi nikao programiranje dve funkcije i forme sa dugmetom ne lici na najkrace resenje. Deluje mi da je ovo probelm tipa 'samo ovaj put i nikad vise'. Ako je tako, nema svrhe razvijati sistem koji ce da proverava postojanje tabele, programski dodaje autoincrement kolonu i slicno. Getsbijevo resenje je mnogo blize 'quick and dirty'. Ako je zadatak 'sad i nikad vise', nije bitno da li ce kod da se izvrsi za 3, 33 ili 333 sekunde. 333 sekunde je dovoljno vremena da se popije kafa ili prveri privatni mejl u radno vreme. Pitanje je samo sta je brze - napisati quick and dirty kod kao sto Getsbi predlaze ili kreirati tabelu i odraditi kveri kao sto ja predlazem. Zavisi od ukusa i vestine. Na primer, moji programeri na poslu brze pisu kod nago sto ja pisem kverije pa ih je ponekda tesko ubediti da je 'best code is nocode at all'. I da ne bude greske, ne kritikujem nego pozdravljam doprinos koji je dao domaci_a_nas. Mi u stvari ne znamo da li je u pitanj quick and dirty ili nesto trajnije. Ako je u pitanju nesto trajnije, domaci_a_nas nudi pravu stvar. Posto forum citaju i drugi, kojima mozda treba trajnije resenje, onda ce oni imati vise koristi od domaci_a_nas resenja nego od quick and dirty ideja. Mogu da kazem, kompletan set odgovora, sa mnogo opcija, pa kome sta treba, bujrum, kako kazu u Bosni. ![]() [ domaci_a_nas @ 11.03.2008. 13:19 ] @
Hteo sam da kažem da se ovaj kod dosta brzo izvršava, ne da se može napisati za kratko vreme. Svako problem posmatra iz nekog svog ugla, moj prioritet je očuvanje integriteta podataka u tabeli sa 150 000 podataka i pretpostavio sam ipak da je moguće da ID polje nije baš 1, 2, 3, 4, jer ako je prilikom unosa podataka korisnik pritisnuo cancel, autonumber bi preskočio jedan broj. Što se For / Next petlje tiče, u tom slučaju bi trebalo znati tačan broj recorda. Funkcije koje su prikazane u mom kodu koristim svakodnevno i smatram ih vrlo praktičnim.
Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|