Avatar billede Slettet bruger
02. maj 2006 - 13:02 Der er 19 kommentarer og
1 løsning

Random post fra db med prioritet

Jeg bruger denne kode til at hente tilfældige bannere ud fra min access db, men den taget et tilfældigt banner ud fra hele flokken. Jeg vil gerne have den til vise dem med højest prioritet flest gange osv.

Noget ligende det her:
0 = Aldrig
1 = Sjældent
2 = Normalt
3 = Ofte
4 = Meget ofte

Om det kommer til at køre efter 100% skala eller hvordan det ellers kunne gøres, er fuldstændig lige meget.

Min nuværende kode:

<%
Set rsBanner = Server.CreateObject("ADODB.RecordSet")
strSQL = "select * From banners where bValid=true AND bSize=120"

    rsBanner.Open strSQL, ConnMain, 3, 1

If not rsBanner.EOF or not rsBanner.BOF Then
Randomize
rsBanner.Move(int(rsBanner.RecordCount * rnd))

Response.Write rsBanner("bCode")

End If
%>
Avatar billede fennec Nybegynder
02. maj 2006 - 13:20 #1
Du skal have lavet en ekstra tabel med en enket kolonne
navn: antalVisninger
Kolonne: vis
Data (test):
2
4
4
4

Dette kan du bruge til at joine med:
strSQL = "select b.* From (banners b inner join antalVisninger av on av.vis=b.visType) where bValid=true AND bSize=120"

Joinet gør at de enkelte rækker bliver gentaget så mange gange som tallet forkommer i antalVisninger tabellen. F.eks vil der kun blive vist de rækker med 2 og 4, men rækker med 4 vil blive vist 3 gang, og derved være større sandsynlighed for at de bliver vist som banner.

Forstod du det?? For jeg har svært ved at forklare det :o)

Data i tabellen skal være noget i denne stil i stedet for de test data jeg havde:
1
2
2
3
3
3
4
4
4
4
Avatar billede ldanielsen Nybegynder
02. maj 2006 - 13:24 #2
Jeg er enig med fennec, men jeg vil hellere lave et array med bannerne, hvor bannerne bliver gentaget det antal gange som angives i prioritet

Derefter henter man et random banner fra arrayet.
Avatar billede Slettet bruger
02. maj 2006 - 13:27 #3
Kan godt se noget af det du mener, men hvorfor lave en tabel til og køre igennem inner join ?
Hvis jeg forstår det rigtigt, ville det så ikke være nemmere at lave en forspørgsel i access og så køre SQL'en igennem den ?
Avatar billede ldanielsen Nybegynder
02. maj 2006 - 13:28 #4
Åbn rsBanner med

strSQL = "select bCode, intPriority From banners where bValid=true AND bSize=120 AND intPriority > 0"

Derefter looper du igennem:

do while not rsBanner.EOF
  for i = 0 to rsBanner("intPriority")
    'tilføj rsBanner("bCode") til array'et
  next
loop

'Vælg nu et random bCode fra array'et
'Find så posten i rsBanner med det fundne bCode

er du med?
Avatar billede Slettet bruger
02. maj 2006 - 13:29 #5
ldanielsen >>> Er ikke 100% inde i det med array's men vil det ikke sige at man skal hente alle banner ud fra db'en og der efter vælge et ? Vil det så ikke sløve serveren en hel del hvis der nu er feks 300 bannere !?
Avatar billede fennec Nybegynder
02. maj 2006 - 13:30 #6
ldanielsen >>
Det kunne man også, men der ville jeg fortrække DB metoden.
Men jeg er også DB mand, hvorfor jeg har det med at fortrække DB løsninger :o)

gizmo2000 >>
Det er en join egenskab at hvis et idforkommer flere gange, bliver rækkerne gentaget.

Et eksempel:

Banner data:
[id, navn, url, visType}
1, "navn1", "url1", 2
2, "navn2", "url2", 4

antalVisninger data
[vis]
2
4
4
4

denne select vil give dette resultat
select b.* From (banners b inner join antalVisninger av on av.vis=b.visType)
1, "navn1", "url1", 2
2, "navn2", "url2", 4
2, "navn2", "url2", 4
2, "navn2", "url2", 4
Avatar billede fennec Nybegynder
02. maj 2006 - 13:32 #7
Det er også pga denne egenskab at "distinct" metoden blev lavet, så man kunne undgå at rækker bliver gentaget, men i dette tilfælde kan du udnytte det :o)
Avatar billede ldanielsen Nybegynder
02. maj 2006 - 13:35 #8
Set rsBanner = Server.CreateObject("ADODB.RecordSet")
strSQL = "select bCode, intPriority From banners where bValid=true AND bSize=120 AND intPriority > 0"
rsBanner.Open strSQL, ConnMain, 3, 1


Redim Preserve arrBannere(-1)
If not rsBanner.EOF or not rsBanner.BOF Then
  Redim Preserve arrBannere(-1)
  do while not rsBanner.EOF
    for i = 0 to rsBanner("intPriority")
      Redim Preserve arrBannere(Ubound(arrBannere)+1)
      arrBannere(Ubound(arrBannere)) = rsBanner("bCode")
    next
  loop
  Randomize
  Response.Write(arrBannere(Ubound(arrBannere) * rnd))
end if
Avatar billede Slettet bruger
02. maj 2006 - 13:36 #9
fence >>> Vil det sige at når jeg tilføjer ET banner til databasen med en prioritet på 5 så vil den faktisk oprette 4 banner med samme info !?
Avatar billede ldanielsen Nybegynder
02. maj 2006 - 13:37 #10
Du har ret, det betyder ekstra belastning.

Derfor ville jeg kun hente bannerid'erne ud, finde det id der skal vises, og så hente banneret fra databasen.

Det giver to forespørgsler, men kun meget lidt data skal flyttes
Avatar billede ldanielsen Nybegynder
02. maj 2006 - 13:39 #11
HOV HOV

Jeg mangler et rsBanner.MoveNext !!!!


do while not rsBanner.EOF
  for i = 0 to rsBanner("intPriority")
    Redim Preserve arrBannere(Ubound(arrBannere)+1)
    arrBannere(Ubound(arrBannere)) = rsBanner("bCode")
  next
  rsBanner.MoveNext
loop
Avatar billede Slettet bruger
02. maj 2006 - 13:46 #12
ldanielsen >>> Jeg er lige igang med at teste din kode og den ser ud til at virke, men hvor store skal springene i prioriteterne være før at det har en god effekt.
Har testet med 1,2,5 og 5 vises selvfølgelig flest gange, men 1 vises også en del gange... Nu skal det lige siges at der kun er 3 bannere i db'en.
Avatar billede ldanielsen Nybegynder
02. maj 2006 - 13:50 #13
Et banner med prio 2 vises dobbelt så mange gange som et med prio 1

I dit tilfælde er der 8 poster i array'et, så det banner med prio 1 bliver vist ca hver 8. gang
Avatar billede Slettet bruger
02. maj 2006 - 13:58 #14
Okay, jeg tror jeg holder mig til denne kode, da den ikke kræver den helt store database ændring.
Men i skal selvfølgelig have mange tak for hjælpen begge to og hvis i lægger et svar hver så deler jeg pointne 70/30. Det tror jeg nok jeg kan finde ud af :)
Avatar billede ldanielsen Nybegynder
02. maj 2006 - 14:04 #15
Tak for det.

Du kan iøvrigt overveje at gemme array'et med samtlige bannerID i en Application variabel. Den skal så opdateres hver gang du retter i databasen, men du sparer et hug i databasen hver gang et baner skal vises.

Gem IKKE recordsets i Application variabler!!!
Avatar billede fennec Nybegynder
02. maj 2006 - 14:25 #16
Jeg behøver ikke point.
.o) <-- One Eyed Jack
Avatar billede Slettet bruger
02. maj 2006 - 15:11 #17
ldanielsen >>> Der er vist lidt for mange ukendte ord i det svar der ;) Du mener at hver besøgende gemmer alle bannerID's i en slags session så de ikke har nød at hente bannerID's hver gang de skifter side ?

fennec >>> Syntes bare du skulle have lidt for ulejligheden, dit svar havde jo sikkert også virket som det skulle :)
Avatar billede ldanielsen Nybegynder
03. maj 2006 - 08:48 #18
"Du mener at hver besøgende gemmer alle bannerID's i en slags session så de ikke har nød at hente bannerID's hver gang de skifter side ?" >>

Ja, lige præcis! Hvis du gemmer array'et i en Session variabel, så kan det lade sig gøre at hver bruger henter det fra databasen første gang, og så genbruger det på følgende sider.

Men en Application variabel kan bruges at alle brugere, den er fælles, så på den måde sparer du endnu mere.
Avatar billede fennec Nybegynder
03. maj 2006 - 09:25 #19
Det handler ikke om løsningen virker, men hvilken du vælger.
Desuden skal jeg bare have point nok til at komme i top 100 så jeg bibeholder mit PRO-medlemskab (ja, alle i månedens top 100 bliver PRO medlemmer), og det skal jeg nok klare alligevel. Så bare giv alle point til ldanielsen :o)
Avatar billede ldanielsen Nybegynder
03. maj 2006 - 14:32 #20
Tak for det
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester