select from - mysql

dobrý den, mám problém se sosáním dat z databáze. chci si vytáhnout náhodných 20 záznamů, k tomu mam příkaz "SELECT FROM TEST ORDER BY RAND() LIMIT 20;" bohužel se neprovede, pokud obsahuje "order by rand"..dá se to ošetřit nějak jinak? nebo nemáte někdo nějaký tip co s tím? předem děkuji :)
Jestli je to přesný zápis, pak máš neúplný SQL dotaz. Parametr SELECT musí obsahovat nějaké sloupce.

SELECT * FROM TEST ORDER BY RAND() LIMIT 20;

Jinak nevidím žádný důvod, proč by to nemělo fungovat.
Po doplnění seznamu sloupců dotaz samozřejmě fungovat bude.

Dodám ale krátkou optimalizační poznámku k výkonu. Tento zápis způsobí, že databáze první ke každému záznamu v tabulce (nad kterou se provádí tento dotaz) vygeneruje (pseudo)náhodné číslo a teprve později podle těchto čísel seřadí a následně výběr omezí na prvních 20. Pokud je v tabulce například 10k záznamů, takovýto postup už spotřebuje docela velké množství času.

Stojí proto za zvážení, jestli opravdu náhodné seřazení potřebuješ. Pokud ano, podle okolností existují lepší postupy, jak docílit stejného výsledku:
a) Pokud má každý záznam v tabulce unikátní číselné id (a v rozmezí nejmenší id - největší id žádné nechybí), stačí v prvním dotazu načíst nejmenší a největší id. V PHP vygenerovat náhodná čísla z takového rozsahu a nakonec načíst záznamy z tabulky podle těchto náhodných id.
b) Pokud má každý záznam v tabulce unikátní číselné id a některá id chybí, existuje více možností. Nejjednodušší spočívá v rozšíření prvního postupu z bodu a) do stavu, kdy v případě náhodného výběru neexistujícího id prostě vygeneruješ další náhodná id (takový postup ale samozřejmě nebude fungovat na řídkých tabulkách, protože se náhodnými čísly budeš povětšinou trefovat na neexistující záznamy). Druhá možnost je načtení seznamu všech id z tabulky (tento dotaz je vždycky stejný a lze na něj rozumně použít cache) následný náhodný výběr id v PHP a načtení zvolených záznamů.

___
Postupy z bodu b) jsou hodně závislé na konkrétní situaci. Pokud je záznamů v tabulce opravdu málo (např. okolo 40) a jejich číselné id není v řadě, může být nejlepším řešením klidně i původní uvažovaný dotaz.
Zkoušel jsem původní verzi u sebe na 1 milionu krátkých záznamů, doba 8 sekund. Pokud jsem náhodná čísla vygeneroval předem (dle postupu a), doba se výrazně zkrátila do řádu milisekund.

Pro malé množství záznamů (cca do 1000) bych to neřešil a nechal bych původní variantu. Na WZ bych s tím limitem šel ještě o kousek níž.

O něco rychlejší byla verze
SELECT * FROM test WHERE id IN (SELECT id FROM test ORDER BY rand() LIMIT 20);
Při 4 milionech záznamů se to projevilo zkrácením doby o 1/3, u delších záznamů byl rozdíl ještě výraznější.
omlouvám se, napsal jsem to špatně, tu * tam mam, ale stejně mi to nefachá..stránky jsou na www.automobilove-systemy.wz.cz a celý kod je následující :
<?
session_start();
$spojeni=MySQL_Connect("mysql.webzdarma.cz","db","heslo");
$databaze=MySQL_Select_DB("automobiloves",$spojeni);
function generuj(){
$i=0;
$sql1 = "SELECT * FROM test ORDER BY RAND () LIMIT 20";
$vypis1 = mysql_query($sql1);
while($zaznam = MySQL_Fetch_Array($vypis1)){
$id[$i]= $zaznam['id'];
$_SESSION['otazky'][$i]=$id[$i];
$i++;
}}
?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1250">
<meta name="description" content="Webová stránka o elektronicky řízených systémech v automobilech a jejich vlivu na bezpečnost silničního provozu.">
<meta name="keywords" content="automobil, elektronika, system, rizeni, test, otazky">
<title>Elektronicky řízené systémy - automobilové technologie</title>
<link rel="stylesheet" type="text/css" href="format.css">
</head>
<body id="zaklad">
<?
if (empty($_POST)){
generuj();
?><h1>Test</h1><?
$cislo=1;
for ( $i=0; $i<=19;$i++)
{
$id[$i]=$_SESSION['otazky'][$i];
$sql2 = "SELECT * FROM test where id='$id[$i]'";
$vypis2 = mysql_query($sql2);
while($zaznam = MySQL_Fetch_Array($vypis2)){
$otazky[$i] = $zaznam["otazka"];
$moznosti[$i] = array($zaznam["a"], $zaznam["b"], $zaznam["c"]);
shuffle($moznosti[$i]);
$a=$moznosti[$i][0];
$b=$moznosti[$i][1];
$c=$moznosti[$i][2];
?>
<form name='test' action='<?php echo $_SERVER['PHP_SELF'];?>' method='POST' onSubmit="return kontrola(test);">
<fieldset id="radia"><legend id="otazka"><b><?echo $cislo.") ".$otazky[$i]?></b></legend>
<input type="radio" name="<?echo $id[$i]?>" value="<?echo $a?>"><?echo $a?>
<input type="radio" name="<?echo $id[$i]?>" value="<?echo $b?>"><?echo $b?>
<input type="radio" name="<?echo $id[$i]?>" value="<?echo $c?>"><?echo $c?>
</fieldset>
<?$cislo++; }} ?>
Vaše jméno: <input type="text" name="jmeno" value="Zadejte jméno" onfocus="this.value=''"><br>
<input type="submit" name="odeslat" value="Vyhodnotit"><input type="reset" value="Vymazat"></center>
</form>
<script language="JavaScript">
function kontrola(){
if(document.test.jmeno.value == "" || document.test.jmeno.value == "Zadejte jméno"){
alert("Vyplňte jméno, pod kterým se Váš výsledek uloží do databáze !");
test.jmeno.focus();
return false;}}
</script>
<?
}else{
?><h1>Vyhodonocení</h1><?
$cislo=1;
$vysledek=0;
$jmeno=$_POST['jmeno'];
echo "Vaše jméno: ".$jmeno."<br><br>";
for ( $i=0; $i<=19;$i++) {
$id[$i]=$_SESSION['otazky'][$i];
$sql3 = "SELECT * FROM test where id='$id[$i]'";
$vypis3 = mysql_query($sql3);
while($zaznam = MySQL_Fetch_Array($vypis3)){
$otazky[$i] = $zaznam["otazka"];
$spravne[$i] = $zaznam["a"];
$odpoved[$i]= $_POST["$id[$i]"];
echo "<div id='tucne'>".$cislo.") ".$otazky[$i]."</div>";
if ($spravne[$i]==$odpoved[$i]){
$vysledek++;
echo "<div id='spravna1'>"."Vaše odpoveď"." - ";
echo $odpoved[$i]."</div><br>";
}else{
echo "<div id='spatna'>"."Vaše odpoveď"." - ";
echo $odpoved[$i]."</div>";
echo "<div id='spravna2'>"."Správná odpoveď"." - ";
echo $spravne[$i]."</div><br>";
}
$cislo++;
}}
$procenta=($vysledek/20)*100;
echo "<div id=vysledek>";
echo "Počet správných odpovědí: ".$vysledek."<br>";
echo "Test byl splněn na ".$procenta." %"."<br>";
echo "<a href='test3.php'>"."Zkusit znova"."</a>";
echo "</div>";
session_destroy;
}
?>
MySQL_Fetch_Array() je funkce, která vrací pole. Může pole nabývat hodnoty false nebo true? Asi ne. Pokud místo while použiješ foreach, tak to možná pojede.

Proměnnou $i můžeš ze všech cyklů odstranit. Není potřebná.