Avatar billede nicklasb Nybegynder
20. februar 2003 - 12:45 Der er 13 kommentarer og
1 løsning

MySQL/PHP. Vælg en række random resultater ud

Hej eksperter

Så har jeg lige brug for lidt assistance til noget MySQL/PHP.
Jeg er i gang med at lave et banner-rotationssystem. Jeg har oprettet en database (med lige nu 5) forskellige bannere i. Det er som heller ikke der problemet ligger. Problemet er at få printet dem ud. Jeg vil gerne have at den helt tilfældigt vælger et x antal af bannerne og herefter printer dem ud i en helt tilfældig rækkefølge.

Det drejer sig om denne side, hvis det hjælper på forståelsen af hvad jeg vil: http://www.bornstein.dk/swom/hist.php

Jeg lavede først dette script:

----------------------------------------kode----------------------------------------

<?php

    $pr_ekz_height = 75;
    $pr_ekz_width = 100;
    $pr_public_zerro = 0;

    $pr_public_query = "SELECT id, pic, title FROM swim_pr_publicity WHERE height='$pr_ekz_height' AND width='$pr_ekz_width' AND status='1'";
    $pr_public_res = mysql_query($pr_public_query) or die(mysql_error());

    while($pr_public_resl = mysql_fetch_array($pr_public_res)) {

    $pr_public_id[$pr_public_zerro] = $pr_public_resl["id"];
    $pr_public_pic[$pr_public_zerro] = $pr_public_resl["pic"];
    $pr_public_title[$pr_public_zerro] = $pr_public_resl["title"];
   
    $pr_public_zerro = $pr_public_zerro+1;

    }
    $pr_public_antal = mysql_num_rows($pr_public_res);
   
    srand ((float)microtime()*1000000);
    for ($i=0;$i<$pr_public_antal;$i++) {
    $udtraek[]=$i;
    }
    shuffle($tabel);
    $reklamenr1 = $udtraek[0];
    $reklamenr2 = $udtraek[1];
    $reklamenr3 = $udtraek[2];
    $reklamenr4 = $udtraek[3];

echo "      <div style=\"height: 25%;\">
      <div class=\"reklame\"><a href=\"count.php?id=$pr_public_id[$reklamenr1]\" target=\"_blanc\"><img src=\"$site_host/images/pr/$pr_public_pic[$reklamenr1]\" height=\"75\" width=\"100\" alt=\"$pr_public_title[$reklamenr1]\"></a></div>
      </div>
      <div style=\"height: 25%;\">
      <div class=\"reklame\"><a href=\"count.php?id=$pr_public_id[$reklamenr2]\" target=\"_blanc\"><img src=\"$site_host/images/pr/$pr_public_pic[$reklamenr2]\" height=\"75\" width=\"100\" alt=\"$pr_public_title[$reklamenr2]\"></a></div>
      </div>
      <div style=\"height: 25%;\">
      <div class=\"reklame\"><a href=\"count.php?id=$pr_public_id[$reklamenr3]\" target=\"_blanc\"><img src=\"$site_host/images/pr/$pr_public_pic[$reklamenr3]\" height=\"75\" width=\"100\" alt=\"$pr_public_title[$reklamenr3]\"></a></div>
      </div>
      <div style=\"height: 25%;\">
      <div class=\"reklame\"><a href=\"count.php?id=$pr_public_id[$reklamenr4]\" target=\"_blanc\"><img src=\"$site_host/images/pr/$pr_public_pic[$reklamenr4]\" height=\"75\" width=\"100\" alt=\"$pr_public_title[$reklamenr4]\"></a></div>
      </div>
";

?>

---------------------------------------/kode----------------------------------------

Men bag efter fandt jeg ud af at det kunne være godt, hvis man også kunne vælge hvor mange der skulle vises på engang, og det derfor ikke skulle være fastlåst på 4 stykker.
Jeg kom også i tanke om at der da sagtens kunne komme helt op til 20 bannere der passede på mine whiles.

Jeg prøvede derfor at lave et nyt script:

----------------------------------------kode----------------------------------------

<?php

    $pr_ekz_height = 75;
    $pr_ekz_width = 100;
    $pr_public_procent = floor(100/$pr_public_antal);

//    $pr_public_query = "SELECT id, pic, title FROM swim_pr_publicity WHERE height='$pr_ekz_height' AND width='$pr_ekz_width' AND status='1' AND media='1' ORDER BY RAND() LIMIT 0,$pr_public_antal";
//    $pr_public_query = "SELECT id, pic, title, rand() AS tt FROM swim_pr_publicity WHERE height='$pr_ekz_height' AND width='$pr_ekz_width' AND status='1' AND media='1' ORDER BY tt LIMIT 0,$pr_public_antal";
//    $pr_public_query = "SELECT id, pic, title, ((ID*0)+rand()) AS RandomID FROM swim_pr_publicity WHERE height='$pr_ekz_height' AND width='$pr_ekz_width' AND status='1' AND media='1' ORDER BY RandomID LIMIT 0,$pr_public_antal";
    $pr_public_res = mysql_query($pr_public_query) or die(mysql_error());

    while($pr_public_resl = mysql_fetch_array($pr_public_res)) {

    $pr_public_id = $pr_public_resl["id"];
    $pr_public_pic = $pr_public_resl["pic"];
    $pr_public_title = $pr_public_resl["title"];

    echo "      <div style=\"height: $pr_public_procent%;\">
      <div class=\"reklame\"><a href=\"count.php?id=$pr_public_id\" target=\"_blanc\"><img src=\"$site_host/images/pr/$pr_public_pic\" height=\"75\" width=\"100\" alt=\"$pr_public_title\"></a></div>
      </div>
";
    }

?>

---------------------------------------/kode----------------------------------------

Det den gerne skulle gøre er at den allerede i udtrækket skulle vælge 4 tilfældige bannere. Jeg har prøvet med de tre løsningsforslag med //’erne foran. Men det er som om rand() –funktionen i MySQL-en ikke rigtig virker. Den kommer mere eller mindre hver gang frem med samme kombination. Næsten hver gang kommer id nr. 1 først, efterfulgt af id nr. 2. Så kommer enten nr. 3 eller 5, og så til sidst nr. 4. (Prøv på siden at holde musen over bannerne. Så kan I i statusbaren se id’et)
Nogle gange virker den dog, men langt de fleste gange kommer den med dem i næsten numerisk rækkefølge.
Jeg skal have lavet det så det er HELT tilfældigt. Det er som om den lige nu hælder mest til at komme med dem i slavisk rækkefølge.

Jeg tænkte så på at lave en count på alle rækkerne der matchede, og så bagefter i en for-løkke hente dataene fra de forskellige ud.
Men vil det ikke både tage for lagt tid, og kræve for meget af serveren??

Men første version virkede RIGTIG godt. Men jeg tror det bliver et problem når der kommer op til 20-30 matchende resultater der først skal hentes ud i variabler, som så slet ikke bliver brugt til noget

Altså kort og godt, er spøgsmålet: Hvordan skal jeg hurtigst, og mindst serverkrævende få et bedre random-udtag??
Løsningen må gerne benytte PHP, hvis det kunne hjælpe på det.
Men hvordan ville i selv gøre det hvis det var jer der stod med denne opgave?

På forhånd mange tak for hjælpen
/Nicklas B.
Avatar billede sostack Nybegynder
20. februar 2003 - 12:54 #1
Jeg tror du skal prøve at udelade ORDER BY xxxxxx i dine SQL-sætninger, idet de jo netop sorterer efter et kriterie, og altså giver en bestemt rækkefølge på de fundne poster i databasen:
f. eks. :
$pr_public_query = "SELECT id, pic, title, ((ID*0)+rand()) AS RandomID FROM swim_pr_publicity WHERE height='$pr_ekz_height' AND width='$pr_ekz_width' AND status='1' AND media='1' LIMIT 0,$pr_public_antal";
Avatar billede nicklasb Nybegynder
20. februar 2003 - 13:03 #2
jeg har prøvet at ligge det du skriver op nu.. Men  nu tager den KUN dataene ud i en slavisk rækkefølge. Det der var meningen var lige nødagtig at den SKULLE komme ud i en forskellig rækkefølge.

Lige nu kommer den ud som fx 1,2,5,4 eller 1,2,3,4.. Men fælles er at de næsten HVER gang kommer med 1,2,x,4.. Og det er ikke meningen. Det er meningen at alle skal være lige, og at der skal være lige så stor chance for at det er 3'eren der kommer først.
Som sagt, den første af mine forsøg vikede. Men tror den vil kræve for meget. Jeg vil tro at jeg skal bruge en løsning hvor den KUN henter de data ud den skal bruge, og ikke lige som mit første hvor alle dataene bliver lagt i arrays..

Men tak for insatsen, og jeg undskylder hvis jeg ikke havde fået forklaret mig godt nok.. :)
Avatar billede sostack Nybegynder
20. februar 2003 - 13:23 #3
Prøv med:
$pr_public_antal = 2;
$pr_public_query = mysql_query("SELECT id, pic, title, ((id*0)+rand()) AS RandomID FROM swim_pr_publicity ORDER BY RandomID LIMIT 0, $pr_public_antal");
    while ($data = mysql_fetch_array($query)) {
        print $data['title']. "<br>";
    }

så kan du ændre $pr_public_antal til nopget andet senere.
Når du kun har 5 poster og vil vælge 4 tilfældigt, giver det jo ikke så mange muligheder.
Jeg har testet med 11 poster til at generere 5 tilfældige, og de er meget forskellige fra gang til gang.
Avatar billede nicklasb Nybegynder
20. februar 2003 - 13:30 #4
jeg har prøvet at sætte den til 2 nu.. men det er nu stadig posterne med id 1 og id 2 der kommer for det meste..
Og den skulle også gerne kunne klare det selv om der KUN er 5 poster.. Men det jeg godt kunne tænkte mig var også en random rækkefølge. Den vælger for det meste id 1 som den første. Og det kan man jo ikke bruge til noget.
Avatar billede sostack Nybegynder
20. februar 2003 - 13:32 #5
Prøv at lave nogle flere poster i din database, og se om det ikke hjælper.
Avatar billede nicklasb Nybegynder
20. februar 2003 - 13:36 #6
det kan være det kommer til at virke. Men hvis jeg kun får 5 bannere til rådighed skal den jo også kunne vælge en tilfældig rækkefølge ud fra disse. Det holder jo igen steder hvis man sælger et banner, og man så kun bliver vist 20% af fremvisningerne, frem for de andre der har købt lidt tidligere der før vist sit banner 100% af fremvisningerne. Er det ikke muligt at få en radom-funktion der virker lidt bedere??

Jeg vil lige prøve at tilføje nogle flere her om lidt, men det er jo ikke sådan det skal virke..
Avatar billede sostack Nybegynder
20. februar 2003 - 13:48 #7
på http://johnsen-offset.adsl.dk/testarea/randomtest.php kan du se 100 tests af min udgave.
Avatar billede nicklasb Nybegynder
20. februar 2003 - 14:35 #8
jeg har prøvet at tilføje nogle flere nu.. (ialt 11).. Den virker LIDT bedere.. Men banneret med id 1 kommer stadig i 70 af tilfældene til at stå som nr 1 i listen.. og det er jo ikke acceptabelt.. Jeg kan godt se at det virker hos dig.. men det hjælper ikke så meget.. Hvilken version af MySQL kører du med?? jeg bruger en 3.23.54.. Men jeg kan desværre ikke skifte da det ikke er min server den ligger på. (Bare rart at vide om det kunne skyldes den)..
Men hvad kan jeg ellers gøre. Den skal være "mere" random hvis man kan sige det sådan..
Avatar billede nicklasb Nybegynder
20. februar 2003 - 14:47 #9
jeg har på denne side, prøvet at udskrive hvilke resultater der bliver trukket ud ved brug af:
$pr_public_query = "SELECT id, pic, title, ((ID*0)+rand()) AS RandomID FROM swim_pr_publicity WHERE height='$pr_ekz_height' AND width='$pr_ekz_width' AND status='1' AND media='1' ORDER BY RandomID LIMIT 0,$pr_public_antal";

Bare for at gøre det lidt lettere :)
Prøv nu at opdater siden med korte mellemrum..
og lig mærke til de 2-3 øverste. Der kommer hele tiden et 1 -tal.. Altså bliver den vist..

Så jeg ved ikke rigtigt hvad jeg skal gøre for at den tager lidt mere tilfældigt..!
Avatar billede nicklasb Nybegynder
20. februar 2003 - 14:48 #10
hov.. manglede lige link.. http://www.bornstein.dk/swom/test.php ;)
Avatar billede nicklasb Nybegynder
20. februar 2003 - 17:34 #11
er der igen der kan hjælpe mig med at få mit rand() til at virke lidt bedere??
der er ikke noget der hedder srand() mv. i MySQL, vel? Det er kun i PHP eller??
Avatar billede nicklasb Nybegynder
21. februar 2003 - 15:15 #12
er der igen der kan hjælpe med at få det til at virke??
Avatar billede nicklasb Nybegynder
24. februar 2003 - 22:29 #13
ingen der kan hjælpe??
Avatar billede nicklasb Nybegynder
18. april 2003 - 14:50 #14
som i kan se på det tidligere link, virker det fint hvis man laver en løkke på 50 med den i ..

men det virker sku stadig ikke rigtigt når der kun bliver "kaldt op" én gang.. :(

Så jeg lukker igen..
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
Vi tilbyder markedets bedste kurser inden for webudvikling

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