Výpis skupin s náhodným prvkem

Školení, která pořádám

Pokud chceme v seznamu skupin zobrazit také jejich jeden náhodný prvek, napadne nás nejprve asi takovýto kód:

<?php
$result = mysql_query("SELECT * FROM skupiny");
while ($row = mysql_fetch_assoc($result)) {
    $nahodny = mysql_fetch_assoc(mysql_query("SELECT * FROM prvky WHERE skupina = $row[id] ORDER BY RAND() LIMIT 1"));
}
mysql_free_result($result);
?>

Problém s tímto kódem je v tom, že dotazy klade opakovaně při procházení cyklu, takže bude velmi pomalý. Pokud nám z dotazované tabulky stačí jeden sloupec, dá se využít poddotaz:

SELECT nazev, (SELECT nazev FROM prvky WHERE skupina = skupiny.id ORDER BY RAND() LIMIT 1) nahodny FROM skupiny;

Pokud bychom sloupců potřebovali více, tak by se dotaz značně zkomplikoval a neprováděl by se efektivně. Pokud bychom použili prosté spojení tabulek a agregaci, tak vrátí MySQL pro každou skupinu náhodný záznam – náhodný ovšem v tom smyslu, že je to první, který je po ruce, takže většinou pořád ten stejný, i když se na to nedá spolehnout.

Přijďte si o tomto tématu popovídat na školení Návrh a používání MySQL databáze.

Jakub Vrána, Řešení problému, 7.5.2007, diskuse: 14 (nové: 0)

Diskuse

Meluzina:

A co takle:

SELECT prvek,skupina FROM (SELECT prvek,skupina FROM prvky ORDER BY RAND()) as prvky2 GROUP BY skupina

ikona Jakub Vrána OpenID:

Chytré. Pokud bychom chtěli vypisovat i skupiny bez prvků, tak by se tam tabulka skupin musela ještě připojit, podstata myšlenky je ale jasná.

Gorog:

dela to jen me nebo ta reklama google zpusobuje to ze kod musim strasne rolovat do sirky? Opera.

Roman:

Já ze šířkou nemám problém v opeře 9.2

Tomáš Fejfar:

Jo. Mám stejný problém - ve škole. Doma mam AdBlock :D

Shark:

Buď v pohodě. V Opeře se alespoň zobrazuje posuvník u druhého kódu, kdežto když jsem si tuto stránku pokusně prohlídl ve Firefoxu 2.0.0.1 tak se zobrazil neúplný kód končící před slovem náhodný. Myší to sice šlo označit a hejbat s tím, ale když tam nebyl posuvník, tak mě to hned nenapadlo.

ikona Jakub Vrána OpenID:

Můžete mi prosím poslat screenshot? Ani v jednom prohlížeči zmíněné chování nepozoruji.

Když je kód širší než viditelná oblast, tak se zobrazí s posuvníkem - to je ale záměr a s reklamou nijak nesouvisí.

Bob:

Taktéž nevidím druhý kód pouze posuvník na IE7 + Maxthon. Firefox i opera bez problémů.

ikona Jakub Vrána OpenID:

Díky za upozornění. V IE 7 jsem byl schopen tento problém reprodukovat a opravil jsem ho. V ostatních prohlížečích nikoliv.

Gimli2:

Opera 9.2 - Po natazeni obrazku ok. Do te doby se ALT pod obrazkem "Make a Donation" roztah mimo obrazovku a logicky tam byl horizontalni posuvnik. Tedy mozna pricina Gorogova problemu...

ikona Jakub Vrána OpenID:

Díky za upozornění, doplnil jsem tam rozměry a změnil ALT.

johno:

Pozor, ORDER BY RAND() spôsobuje full table scan.

http://akinas.com/pages/en/blog/mysql_random_row/

kozoslon:

ale jak jinak bys udělal výpis náhodného řádku tabulky?

ikona Jakub Vrána OpenID:

Dá se to řešit tak, že zjistíš celkový počet řádků z tabulky a použiješ LIMIT 1 OFFSET $rand, kde $rand si naplníš na aplikační úrovni.

Vložit komentář

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL:

avatar © 2005-2018 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.