Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [MySQL][PHP] Losowe wyświetlanie pytań.
blade-mrn
post
Post #1





Grupa: Zarejestrowani
Postów: 113
Pomógł: 11
Dołączył: 20.10.2009

Ostrzeżenie: (0%)
-----


Witam,
Mam w bazie danych w jednej tabeli zapisane pytania i w drugiej przypisane im odpowiedzi. Pytania są wyświetlane na stronie pojedynczo za pomocą stronicowania.
Chciałbym aby te pytania za każdym razem wyświetlane były w innej kolejności (bez powtórzeń) tyle że nie wiem jak można taki efekt uzyskać. Ma ktoś jakąś radę??
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 11)
Diabl0
post
Post #2





Grupa: Zarejestrowani
Postów: 24
Pomógł: 1
Dołączył: 25.03.2006

Ostrzeżenie: (0%)
-----


ORDER BY RAND()

http://dev.mysql.com/doc/refman/5.0/en/mat...l#function_rand

Ten post edytował Diabl0 7.11.2009, 11:50:53
Go to the top of the page
+Quote Post
blade-mrn
post
Post #3





Grupa: Zarejestrowani
Postów: 113
Pomógł: 11
Dołączył: 20.10.2009

Ostrzeżenie: (0%)
-----


Wszystko fajnie bo ORDER BY RAND() działa tyle że pytania się powtarzają.
Go to the top of the page
+Quote Post
wonski
post
Post #4





Grupa: Zarejestrowani
Postów: 11
Pomógł: 2
Dołączył: 28.04.2007

Ostrzeżenie: (0%)
-----


Musisz sobie zapisywać (np. sesja lub $_GET), które pytania zostały już wykorzystane i wykluczać je z kolejnego zapytania.
Go to the top of the page
+Quote Post
Diabl0
post
Post #5





Grupa: Zarejestrowani
Postów: 24
Pomógł: 1
Dołączył: 25.03.2006

Ostrzeżenie: (0%)
-----


1 - jeśli pytań w teście jest określona liczba (np. 20) - to pobrać cały zestaw pytań od razu i trzymać w sesji
2 - Pytań może być dowolna liczba - zapisywać użyte pytania w sesji i i przy losowaniu nowego pytania odrzucać już użyte pytania albo w samym select (WHERE id NOT IN (1,3) ) albo rekurencyjnie w PHP dopóki nie wylosujesz pytania jeszcze nie używanego. Wybór metody zależy od stosunku pzeciętnej ilości pytań wyświetlanej na usera do ogólnej liczby wszystkich dostępnych pytań i po prostu trzeba sobie samemu sprawdzić co będzie wydajniejsze.
3 - jeśli wyniki odpowiedzi zapisujesz na bazie można napisać select losujący pytanie na które user jeszcze nie ma zapisanej odpowiedzi (select zależny od kontrukcji tabel)

Go to the top of the page
+Quote Post
qrzysztof
post
Post #6





Grupa: Zarejestrowani
Postów: 220
Pomógł: 19
Dołączył: 25.04.2009

Ostrzeżenie: (0%)
-----


Pobrać do tablicy (trzymać w sesji). Tablicę RAZ zrandomizować. A potem zwykłym array_pop.

Funkcja mieszająca tablicę:

  1. public static function randomizeArray ($inArray) #miesza tablice przekazana w argumencie (te same elementy ale w losowej kolejnosci)
  2. {
  3. $tempArray=array();
  4. $inArrayLength=count($inArray);
  5. for ( $i=0; $i < $inArrayLength; $i++ )
  6. {
  7. $rnd=rand();
  8. $tempArray[$i]=$rnd;
  9. }
  10.  
  11. asort($tempArray); #sortuje tablice alfabetycznie (z zachowaniem kluczy)
  12. $randomizedArray=array();
  13.  
  14. $tempKeys=array_keys($tempArray); #zwraca klucze tablicy
  15. foreach( $tempKeys as $key )
  16. {
  17. $randomizedArray[]=$inArray[$key];
  18. }
  19.  
  20. return $randomizedArray;
  21. }
Go to the top of the page
+Quote Post
marcio
post
Post #7





Grupa: Zarejestrowani
Postów: 2 291
Pomógł: 156
Dołączył: 23.09.2007
Skąd: ITALY-MILAN

Ostrzeżenie: (10%)
X----


A zwykly select distinct() z order by rand() nie wystarczy?
Go to the top of the page
+Quote Post
thek
post
Post #8





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




Skoro już jesteśmy przy temacie tablic... To może użyć array_pop() ? To nam automatycznie usunie to pytanie z tablicy (IMG:style_emoticons/default/smile.gif) A to czy my w niej będziemy trzymać całe pytania czy tylko ich numery... A kogo to obchodzi? (IMG:style_emoticons/default/tongue.gif)
Go to the top of the page
+Quote Post
qrzysztof
post
Post #9





Grupa: Zarejestrowani
Postów: 220
Pomógł: 19
Dołączył: 25.04.2009

Ostrzeżenie: (0%)
-----


Cytat(marcio @ 7.11.2009, 19:58:38 ) *
A zwykly select distinct() z order by rand() nie wystarczy?


Może wystarczyć.

Trochę mało danych mamy. Autor mógłby napisać coś więcej w jaki sposób chce pobierać te dane z bazy. Ile tych pytań. Wszystkie na raz, jakiś podzbiór czy po jednym z całości.

Czy przypadkiem randomizacja na poziomie php nie jest efektywniejsza? "Order by Rand()" cieszy się złą sławą.
Go to the top of the page
+Quote Post
blade-mrn
post
Post #10





Grupa: Zarejestrowani
Postów: 113
Pomógł: 11
Dołączył: 20.10.2009

Ostrzeżenie: (0%)
-----


Przede wszystkim dzięki za pomoc.
Nie jako odpowiadając na pytania.
Teoretycznie ilość pytań można sprawdzić bo są one zapisane w bazie i podczas przeprowadzania testu ich ilość się nie zmienia.
Udzielone odpowiedzi są zapisywane w bazie ale pomysł ze wykorzystaniem tego do wyłączenia wyświetlonych już pytań z zapytania jest nie bardzo, bo co w tedy gdy użytkownik nie udzieli odpowiedzi na jakieś pytanie (taka możliwość istnieje)- to pytanie będzie się mu wyświetlać do puki na nie nie odpowie.
Select distinct() też raczej się tu nie sprawdzi bo pytania odczytywane są pojedynczo za pomocą LIMIT.

Ja za Waszą radą kombinowałem tak... Po wyświetleniu pytania zapisuje jego Id do tablicy zapisanej w sesji w celu późniejszego stworzenia ciągu liczb i przecinków np. 42,43,54. Ciąg ten następnie wstawiam do zapytania, na początku to działa bo wyświetla losowo pytania tyle że test ma 5 pytań a wyświetlają się tylko 3, na pozostałych dwóch stronach pytania się nie wyświetlają.
Tak wygląda fragment kodu o którym pisałem.
  1. $result = $db->query("SELECT * FROM pytania WHERE id_test = ".$rek_test['id_test']." AND id_pytania NOT IN (".$_SESSION['oo'].") ORDER BY RAND() LIMIT $start, 1");
  2. echo '<form action="index.php?id=7" method="POST" id="form" onSubmit="zap_czas(c)">';
  3. echo '<table border="0">';
  4. for ($i=1;$i<=$result->num_rows;$i++)
  5. {
  6. $rek_pyt = $result->fetch_assoc();
  7. $_SESSION['tablica'][]=$rek_pyt['id_pytania'];
  8. for ($t=0;$t<=count($_SESSION['tablica']);$t++)
  9. {
  10. if ($t == 0) {$_SESSION['oo'] = $_SESSION['tablica'][$t];}
  11. if (($t > 0) && ($t < count($_SESSION['tablica']))){$_SESSION['oo'] = $_SESSION['oo'].','.$_SESSION['tablica'][$t];}
  12. }
Go to the top of the page
+Quote Post
marcio
post
Post #11





Grupa: Zarejestrowani
Postów: 2 291
Pomógł: 156
Dołączył: 23.09.2007
Skąd: ITALY-MILAN

Ostrzeżenie: (10%)
X----


  1. $result = $db->query("SELECT * FROM pytania WHERE id_test = ".$rek_test['id_test']." AND id_pytania NOT IN (".$_SESSION['oo'].") ORDER BY RAND() LIMIT $start, 1");


Po pierwsze wydaje mi sie ze nie dziala dlatego ze sesja oo moze zawierac kilka wartosci a ty do zapytanie dajesz cala sesje oo jako jeden ciag.

Reszty kodu nie sprawdzalem ale zrob sobie print_r($_SESSION['oo']) po ostatnim for i zobacz czy mam racje.

Go to the top of the page
+Quote Post
blade-mrn
post
Post #12





Grupa: Zarejestrowani
Postów: 113
Pomógł: 11
Dołączył: 20.10.2009

Ostrzeżenie: (0%)
-----


Sesja oo według mojego założenia ma przechowywać tylko jeden ciąg znaków np. 76,34,23 itd. i tak jest.
Sprawdzałem to za pomocą print_r.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 23.08.2025 - 06:20