[PHP/SQL] Losowanie rekordu bez powtórzeń

Języki, których efekty są wykonywane po stronie serwera. PHP, ASP czy CGI w połączeniu z bazami danych SQL dają niezwykłe możliwości budowy i zarządzania stron WWW. Tu zadajemy pytania oraz demonstrujemy kod, z którym mamy problem.
pelzak
Posty: 13
Rejestracja: pt sty 06, 2006 3:52 pm

[PHP/SQL] Losowanie rekordu bez powtórzeń

Post autor: pelzak »

Witam!

[php]<?php
$db=pg_connect("dbname=aaa user=aaa password=abc");

$sel=pg_exec($db,"select id_pytania,tresc from pytania where id_testu=$id_testu order by random() limit 1");

for ($i=0;$i<pg_NumRows($sel);$i++)
list($id_pytania,$tresc)=pg_Fetch_Row($sel);

echo "<b>$tresc ?</b>";

?>[/php]

Aby uniknac wylosowania ponownie tego samego pytania potrzebuje, aby ID pytania było zapisywane np. w tablicy. Potem po losowaniu kolejnego pytania trzebaby sprawdzac czy obecne ID juz nie wystapilo. Jezeli juz było to losujemy ponownie. Jezeli nie to wyswietlam pytanie.

Dodam jeszcze, ze pytania sa wyswietlane pojedynczo (losuje, wyswietla pytanie z odp, uzytkownik zaznacza odp i wciska dalej; i tak w kolko az zakonczy test)

Jakby ktos mogl to prosze o napisanie wlasnie takiego skryptu. Poniewaz probowalem na rozne sposoby rozwiazac ten problem, ale nigdy mi sie nie udawalo.

Słyszałem o DISTINC. Zastosowałem je, ale i tak powtorzylo sie pytanie.
[php]<?php
$sel=pg_exec($db,"SELECT DISTINCT id_pytania,tresc, random() FROM pytania WHERE id_testu=1 ORDER BY 3 LIMIT 1");
?>[/php]

Pozdrawiam
iro
Moderator
Posty: 402
Rejestracja: pt gru 19, 2003 8:20 pm
Lokalizacja: Szczecin

Re: [PHP/SQL] Losowanie rekordu bez powtórzeń

Post autor: iro »

Hmm... A nie lepiej byłoby Ci wybrać z bazy od razu wszystkie rekordy w losowej kolejności, wyniki umieścić w tablicy a potem przechodzić przez tablicę?
pelzak
Posty: 13
Rejestracja: pt sty 06, 2006 3:52 pm

Re: [PHP/SQL] Losowanie rekordu bez powtórzeń

Post autor: pelzak »

Ciekawa sugestia.

A jak pozniej przekazywac kilka razy cala tablice ??
Moze jakis przyklad.
iro
Moderator
Posty: 402
Rejestracja: pt gru 19, 2003 8:20 pm
Lokalizacja: Szczecin

Re: [PHP/SQL] Losowanie rekordu bez powtórzeń

Post autor: iro »

Całą tablicę możesz umieścić chociażby w sesji.
rafcio8405
Nowy
Nowy
Posty: 43
Rejestracja: śr gru 14, 2005 12:47 pm
Lokalizacja: Warszawa
Kontakt:

Re: [PHP/SQL] Losowanie rekordu bez powtórzeń

Post autor: rafcio8405 »

iro pisze:Hmm... A nie lepiej byłoby Ci wybrać z bazy od razu wszystkie rekordy w losowej kolejności, wyniki umieścić w tablicy a potem przechodzić przez tablicę?
Troche dużawa Ta tablica jest jeśli rekorów jest duzo. Ja by pobrał ID do tablicy, potem funkcja losowania (miesznia), a anastępnie jeśli coś jest potrzebne z tej tablicy to bym odczytywał i do osobnej zmiennej zapisywał tylko adres na którym zakończyłem odczytywanie wartości.

Przykład algorytmu:

Kod: Zaznacz cały

 $tablica = (0, 1, 2, 3) 
Po wymieszaniu:

Kod: Zaznacz cały

 $tablica_wymieszana = (3,1,0,2) 
Odczytywanie:

Kod: Zaznacz cały

 $adres = 0
print $tablica_wymieszana[$adres]
viraptor
Zaczyna działać
Zaczyna działać
Posty: 633
Rejestracja: pn cze 28, 2004 12:58 pm
Kontakt:

Re: [PHP/SQL] Losowanie rekordu bez powtórzeń

Post autor: viraptor »

Ale można w ten sam sposób co na samej górze pobrać kilka rekordów:
[sql]select id_pytania,tresc from pytania where id_testu=$id_testu
order by random() limit $ilosc[/sql]
I dostajesz ile chcesz, nie powtarzających się rekordów i używasz tyle pamięci ile naprawde potrzebujesz.
pelzak
Posty: 13
Rejestracja: pt sty 06, 2006 3:52 pm

Re: [PHP/SQL] Losowanie rekordu bez powtórzeń

Post autor: pelzak »

Moglby ktos zademonstrowac jak umiesic tablice $id_pytan z ponizszego kodu w sesji. Nigdy tego jeszcze nie robilem.

[php]<?php

$sel=pg_exec($db,"SELECT DISTINCT id_pytania, random() FROM pytania where id_testu=$id_testu order by random() LIMIT $liczba_p");
for ($i=0;$i<pg_NumRows($sel);$i++)
{
list($id_pytania)=pg_Fetch_Row($sel,$i);
$id_pytan[$i]=$id_pytania;
}

?>[/php]

~rafcio8405 sprytne rozwiazanie. Tylko jednego nie jaze. Jak wymieszac elementy w tablicy.

~viraptor wiem to jest najlepsze rozwizanie. Tylko pozostaje powyzszy problem. Jak zachowac tablice.
rafcio8405
Nowy
Nowy
Posty: 43
Rejestracja: śr gru 14, 2005 12:47 pm
Lokalizacja: Warszawa
Kontakt:

Re: [PHP/SQL] Losowanie rekordu bez powtórzeń

Post autor: rafcio8405 »

Miałem kiedyś na wykładach co prawda w C ale PHP tak dużo od niego się nie różni jak znajde to zapodam, ale ideologia rozwiązania to "Wariacje bez powtórzeń" (Jeżeli z określonych elementów mamy wybrać kilka, tak, że nie będą się one powtarzały,ale z treści zadania wynika, że kolejność wybranych elementów odgrywa rolę, wówczas należy skorzystać z wariacji bez powtórzeń.). Jak znajde to napisze.


PS: Sory to Kombinacje

Jeżeli z określonych elementów mamy wybrać kilka i kolejność wybranych elementów nie odgrywa roli, wówczas korzystamy z kombinacji.
viraptor
Zaczyna działać
Zaczyna działać
Posty: 633
Rejestracja: pn cze 28, 2004 12:58 pm
Kontakt:

Re: [PHP/SQL] Losowanie rekordu bez powtórzeń

Post autor: viraptor »

Jak już masz sesje wystartowaną przez session_start(), to robisz
[php]<?php
$_SESSION['id_pytan']=$id_pytan;
?>[/php]
Wsio. Czytasz też z $_SESSION[...]
rafcio8405
Nowy
Nowy
Posty: 43
Rejestracja: śr gru 14, 2005 12:47 pm
Lokalizacja: Warszawa
Kontakt:

Re: [PHP/SQL] Losowanie rekordu bez powtórzeń

Post autor: rafcio8405 »

Wpadłem na pomysł Używając funkcji Random() i zmiennej zawierającej ilość elementów w tablicy (oczywiście tablice).

Za pomocą funkcji Random wylosować adres elementu Tablicy, następnie przenieść ją na koniec tablicy poczym odjąć 1 element od ilości wsystkich w tej tablicy.

Kod: Zaznacz cały

krok 1
$elementow = 4
$tablica = (1,2,3,4)
$tablica_mieszaj[1] =random($elementow) // 2

krok 2
$elementow = 3
$tablica = (1,3,4,2)
$tablica_mieszaj[2] =random($elementow) // 1

krok 3
$elementow = 2
$tablica = (3,4,2,1)
$tablica_mieszaj[3] =random($elementow) // 1

krok 4
$elementow = 1
$tablica = (4,2,1,3)
$tablica_mieszaj[3] =random($elementow) // 1

Oczywiście tą funkcje można udoskonalić ;) Ja już widze jak ;)
pelzak
Posty: 13
Rejestracja: pt sty 06, 2006 3:52 pm

Re: [PHP/SQL] Losowanie rekordu bez powtórzeń

Post autor: pelzak »

Dzieki za pomoc wszystkim.

Pomogliscie mi w rozwiazaniu problemu. Moge lecie dalej z programem. :-D
ODPOWIEDZ