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.

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: Reakce na: Gorog

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.
avatar © 2005-2020 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.