Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [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ę??


--------------------
"Wszyscy wiedzą, że czegoś nie da się zrobić, i przychodzi taki jeden, który nie wie, że się nie da, i on to właśnie robi."
Albert Einstein
Go to the top of the page
+Quote Post
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


--------------------
Blog
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ą.


--------------------
"Wszyscy wiedzą, że czegoś nie da się zrobić, i przychodzi taki jeden, który nie wie, że się nie da, i on to właśnie robi."
Albert Einstein
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)



--------------------
Blog
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. }


--------------------
Znalazłeś sam rozwiązanie swojego problemu? Nie pisz "już wiem, do zamknięcia". Podziel się rozwiązaniem - inni będą mieli łatwiej.
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?


--------------------
Zainteresowania: XML | PHP | MY(SQL)| C# for .NET | PYTHON
http://code.google.com/p/form-builider/
Moj blog
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 smile.gif A to czy my w niej będziemy trzymać całe pytania czy tylko ich numery... A kogo to obchodzi? tongue.gif


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
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ą.


--------------------
Znalazłeś sam rozwiązanie swojego problemu? Nie pisz "już wiem, do zamknięcia". Podziel się rozwiązaniem - inni będą mieli łatwiej.
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. }


--------------------
"Wszyscy wiedzą, że czegoś nie da się zrobić, i przychodzi taki jeden, który nie wie, że się nie da, i on to właśnie robi."
Albert Einstein
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.



--------------------
Zainteresowania: XML | PHP | MY(SQL)| C# for .NET | PYTHON
http://code.google.com/p/form-builider/
Moj blog
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.


--------------------
"Wszyscy wiedzą, że czegoś nie da się zrobić, i przychodzi taki jeden, który nie wie, że się nie da, i on to właśnie robi."
Albert Einstein
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 19.08.2025 - 19:52