Autor Zpráva
unlucky
Profil
mam skript, ktery ma nahodne vybrat data z databaze. Nechci pouzit rand protoze je pomaly.

$total=mysqli_fetch_assoc(mysqli_query($db,"select max(id) as tot from neco"));
$random=rand(1,$total['tot']);
$data=mysqli_query($db"select * from neco...where id = $random");

Nyni chci, aby se v pripade, kdyz dane id neexistuje, nevrati se zadna data, tak se cely proces zopakuje. Jak to udelat?
Jan Tvrdík
Profil
unlucky:
Nechci pouzit rand protoze je pomaly.
Proč si to myslíš?

kdyz dane id neexistuje, nevrati se zadna data, tak se cely proces zopakuje
Obal to celé do-while cyklem.
unlucky
Profil
a co mam napsat do while?
noname
Profil *
$data=mysqli_query($db"select * from neco ORDER BY RAND() LIMIT 1");


aha bez rand: pokud vím, že tam nějaký záznam je, tak by možná stačilo $data=mysqli_query($db"select * from neco...where id <= $random LIMIT 1");


jinak je tam syntaktická chyba a proměnná by mohla být lépe ".$random." - důležité je <= a limit 1
Chuchycek
Profil
A nestačilo by ti jen rand v sql? Osobně si myslím, že rand je optimální pro tvůj případ.

do{
$total=mysqli_fetch_assoc(mysqli_query($db,"select max(id) as tot from neco"));
$random=rand(1,$total['tot']);
}while(!$data=mysqli_query($db"select * from neco...where id = $random"));
Joker
Profil
unlucky:
Nechci pouzit rand protoze je pomaly.
RAND() není pomalý, ORDER BY RAND() je relativně pomalé, protože to musí generovat náhodné číslo pro každý řádek databáze.

To ovšem nebude problém, pokud těch záznamů bude relativně málo (třeba 20, 50, 100). Pak to docela dobře může být rychlejší, než to druhé řešení.

Dál je třeba zmínit, že to řešení s generováním náhodného ID v cyklu bude fungovat dobře jen pokud těch chybějících ID nebude hodně. Ve chvíli, kdy by se třeba důsledkem nějaké chyby do databáze uložilo daleko vyšší ID než mají existující záznamy (třeba mám 1,2,3,4,5 a pak se uloží 10000, nebo třeba nějaký cyklus omylem nageneruje do databáze 10000x stejný záznam a já to pak promažu), to celé zkolabuje.

V některých situacích by možná vyšlo lépe místo MAX vrátit COUNT (tj. počet řádků), určit nějaký náhodný a pak udělat LIMIT řádek,1. Ani není potřeba cyklus.

noname:
where id <= $random LIMIT 1
Ještě by to mělo být seřazené podle ID, v tomto případě sestupně (jinak by to vracelo pořád první záznam).
Ale bude to mít ten problém, že když v té řadě IDček budou „díry“, položka „před dírou“ bude mít vyšší pravděpodobnost vybrání.
Kdybych v tabulce měl ta IDčka 1,2,3,4,5 a 10000, takový „náhodný výběr“ by skoro vždycky vrátil řádek 5.
unlucky
Profil
Joker:
RAND() není pomalý, ORDER BY RAND() je relativně pomalé, protože to musí generovat náhodné číslo pro každý řádek databáze.

Jak mam tedy napsat dotaz bez Order by?
DJ Miky
Profil
Popsal to Joker v [#6]. Můžeš použít řešení spočívající v id <= $random, nebo si zjistit počet řádků, vygenerovat náhodné číslo 1..počet a pak vybrat řádek dotazem ... ORDER BY id LIMIT $random, 1.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: