+2

Resultados Aleatórios com o MySQL

criado por Celso Endo em 10/08/2003 4:27pm
A Solução!!!

Bom, tendo em vista esse problema citado anteriormente eu tive que mudar o código de meu sistema de banners aleatórios. Suponha que os dados de seus anunciantes estejam na tabela 'banners' do banco de dados 'phpbrasil'. E que essa tabela 'banners' tenham os seguintes campos:

ID - id numérico de cada anunciante
titulo - título da página do anunciante
url - url do anunciante
banner - endereço do banner do anunciante

Então, fiz um código com essa idéia:

<?php
$dbHost = 'localhost';
$dbUser = 'user';
$dbPass = 'pass';
$dbDatabase = 'phpbrasil';

// Conectando ao MySQL e selecionando o BD phpbrasil
$con = mysql_connect($dbHost, $dbUser, $dbPass) or die (mysql_error());
mysql_select_db($dbDatabase, $con);

// Selecionando todos os dados da tabela 'banners'
$q = "select * from banners";
$query = mysql_query($q) or die (mysql_error());

// Ver quantos registros possui a tabela
$total = mysql_num_rows($query);

// Pegando um número aleatório entre 1 e $total;
$numero = rand(1,$total);

// Selecionando o registro $numero
$q = "select * from banners order by ID ASC limit ".$numero.",1";
$query = mysql_query($q);

// Resultado da query em array
$resultado = mysql_fetch_array($q);

echo '<a href="'.$resultado['url'].'" title="'.$resultado['titulo'].'"><img src="'.$resultado['banner'].'" width=468 height=60 alt="'.$resultado['titulo'].'"></a>';

?>

Note que não usei mais a função rand() na query em si.

O que eu fiz foi primeiro calcular quantos anunciantes existem no sistema. Então usei a função rand() para gerar um número aleatório entre 1 e o total de anunciantes e guardei esse número na variável $numero. É aí que está a grande sacada! Então fiz a query pra selecionar o dado de número $numero na tabela.

Isso irá funcionar sem o probleminha do clock interno do servidor. Agora quando seu anunciante for ver se o banner dele realmente está no sistema, ele poderá ir dando "reload" até que o banner dele apareça, e não verá apenas um único banner sendo divulgado.

Espero que esse artigo seja útil a alguém que está tendo o mesmo problema que eu já tive.

Sugestões e críticas são sempre bem-vindas!

Abraços,
Celso Endo

Comentários:

Mostrando 1 - 10 de 14 comentários
Thiago Benko disse:
Boa Tarde.

Primeiramente gostaria de parabeniza-lo pelo post, com certeza de grande valia.

Tenho uma dúvida e preciso da ajuda dos colegas. Estou desenvolvendo um QUIZ (Perguntas e respostas) e preciso listar os Campos da tabela aleatoriamente.
Tabela Questões
codigo
pergunta
resposta1
resposta2
resposta3
respostac (correta)

Preciso que a ordem dos campos ao executar a query no php mude aleatoriamente, para que as posições das perguntas não sejam sempre as mesmas.

Desde já, agradeço pela atenção de todos.
02/12/2015 1:46pm (~8 anos atrás)

ops... faltou fechar o comente acima... heehe

?>

pronto fechado;
13/03/2007 8:35pm (~17 anos atrás)

apos ter postado o comentário acima, fui atraz de como trabalhar com os ARRAY que pra ser sincero ainda nao sei direito hehehhe... mas enfim.. a lógica acima funcionou perfeitamente. e segue abaixo o código.

// nao comentei muito o código pq sinceramente nao me arrisco comentar sobre os array, apenas sei que funiona.

como pra mim tudo que se vende é produto... entao considerei o banner como um produto. e ai vai o codigo

#########################################################

<?php //require("conectabanco.php"); ?>
<?

// busca os id (pd_id)da tabela
$sql_sort = mysql_query("SELECT pd_id FROM produto order by pd_id ASC");
// conta quantos registros existem
$total = mysql_num_rows($sql_sort);
// defino que $total será 1 a menos doque o numero de registro contado no banco, pq o array começa a contar do ZERO.
$total = $total-1;
// aqui to colocando os dados de ID do bando no ARRAY
// no exemplo: digamos que temos 3 registro com os id´s "5" e "8" e "9"
// no array ficará mais ou menos assim, 1=>5 e 2=>8 e3=> 9

while($res_sort = mysql_fetch_array($sql_sort)){
$id = $res_sort["pd_id"];
$array[] = $id;
}
// aqui com o rand eu faço um sorteio entre ZERO e o total de registros
$sortiado = rand(0,$total);
// aqui to pegando o ID sorteado, pra entender melhor... seguindo a lógica
// que no array ficou assim 1=>5 e 2=>8 e 3=> 9
// entao se o rand ali sorteou "2" a linha abaixo verá o equivalente no array que é o ID "8"
$id_sortiado = $array[$sortiado];
// faz a busca com base no ID... onde o id do produto é igual ao ID sorteado.
$prod = mysql_query("SELECT * FROM produto WHERE pd_id = '".$id_sortiado."'") or die(mysql_error("Erro com o Banco de Dados"));
$row_prod = mysql_fetch_assoc($prod);
// abaixo to escrevendo a imagem referente ao ID sorteado lincando p exibir ele...
echo "<a href=\"index.php?l=exibir_prod_escolhido&p=produtos&e=".$row_prod['pd_id']."\" ><img src=\"produtos/produto/".$row_prod['pd_fotopq']."\" alt=\"".$row_prod['pd_nome']."\" border=\"0\" class\"input\" width=\"204\" height=\"150\"/ ></a>";
13/03/2007 8:34pm (~17 anos atrás)

Otimo artigo, mas como o Emanuel Fonseca citou acima, (colado logo aki abaixo), terá esse problema de caso o id tenha sido excluido...

pas isso eu tenho uma lógica que daria perfeitamente, usando ARRAY. a logica é a seguinte

iremos contar o o numero de registros.
$total = mysql_num_rows($query);

ok, tendo o numero de registro, iremos fazer uma busca pelos "numeros existentes" no ID.

depois disso, usando while ou DO ou FOR, iremos relacionar os numeros existentes ao numero de contagem

exemplo...
digamos que nosso banco tem 5 registros, e como esse banco foi bem manipulado com insert e delete etc.

nossos id´s que tem no banco são...

6, 9, 14, 33, 99

entao com while iriamos relacionar com uso de ARRAY
em uma matriz que faria o segui..
$reg = 0;
while($total <= $reg){

// aki usando array coloca os id´s assim:

1 = 6
2 = 9
3 = 14
4 = 33
5 = 99

$reg = $reg++
}

depois disso, faz o sorteio e pega o id equivalente ao numero sorteado e dai sim faz o query do banner baseado no id.

Bom a lógica é essa, espero que tenham entendido. mas eu nao sei trabalhar com array, sei que funciona pela lógica, mas eu nunca sei como por o dado dentro da array e depois tirar.


Quote [
Uma correção importante [ responder ]
publicado por Emanuel Fonseca (usuário autenticado) - 2003-08-28 19:32:14

Essa rotina é muito boa, porém tem falhas. Ele faz a contagem do total de records, ou seja, ele da um numero inteiro. Se vc esta usando auto increment, logo terá problemas. Pq? Pq no dia que você excluir um record da tabela vc pode retornar um record inexistente. Exemplo:

total q vc tem 51 records
Remove id 15
Logo vc tem 50 records
Usando a função vc poderá gerar um valor aleatório de 0 a 50, ou seja, pode retornar o id que foi excluido.

Para solucionar basta testar a existencia do id retornado. Caso não exista um location com PHP_SELF resolve, ok!? É uma solução porém pode tornar o script lento.

]
12/03/2007 8:06pm (~17 anos atrás)

Jorge Jardim disse:
E no caso de vc ter q utilizar algum tipo de filtro no banner (por idade, sexo, região...)?
Coloquei um rand no select e um limite maximo de 20 banners. Para q no caso, se meu sistema tiver muitos registros a execução ñ se torne lenta. Assim, mesmo q o mysql me retorne sempre os mesmos 20 banners durante um tempo, ainda assim, terei 1 entre 20 pra escolher com um outro rand, só q dessa vez fora do select.

<?
$sqlb = mysql_query("SELECT id_banner FROM banner [filtro] order by rand() limit 20");
$tt = mysql_num_rows($sqlb);
$num = rand(0,$tt-1);
while($resultado = mysql_fetch_array($sqlb)) {
$banner[] = $resultado[id_banner];
}
$sqlb = mysql_query("SELECT * FROM banner where id_banner = '".$banner[$num]."'");
?>
29/09/2005 7:41am (~18 anos atrás)

Usando o exemplo do Celso, combinado com o exemplo do assombração funcionou perfeitamente.
09/12/2003 11:51am (~20 anos atrás)

Essa rotina é muito boa, porém tem falhas. Ele faz a contagem do total de records, ou seja, ele da um numero inteiro. Se vc esta usando auto increment, logo terá problemas. Pq? Pq no dia que você excluir um record da tabela vc pode retornar um record inexistente. Exemplo:

total q vc tem 51 records
Remove id 15
Logo vc tem 50 records
Usando a função vc poderá gerar um valor aleatório de 0 a 50, ou seja, pode retornar o id que foi excluido.

Para solucionar basta testar a existencia do id retornado. Caso não exista um location com PHP_SELF resolve, ok!? É uma solução porém pode tornar o script lento.
28/08/2003 7:32pm (~20 anos atrás)

Miguel Lohan disse:
Estou tendo este mesmo problema, estou gerando 6 números aleatórios e vou buscar através de uma select, na verdade 6, hehehhe

<?
$condicao = 0;
for ($x=0;$x<6;$x++)
{
mt_srand ((double) microtime() * 1000000);
do
{
$bloqueia = 0;
$numerorand = mt_rand(1,48);
$numerorandarray[$x] = $numerorand;
if ($condicao != 0)
{
for ($loop=0;$loop<sizeof($numerorandarray)-1;$loop++)
{
if ($numerorandarray[$loop] == $numerorand)
{
$bloqueia++;
}
}
}
$condicao=1;
}
while ($bloqueia > 0);
echo $numerorandarray[$x]."<br>";
}

?>
26/08/2003 7:09pm (~20 anos atrás)

Bom digamos que ja tenha sido feito a conexao com o banco de dados....o rand tem uma pequena alteracao

<?
$sqlb = mysql_query("SELECT * FROM banner_pequeno");
$tt = mysql_num_rows($sqlb);
$num = rand(0,$tt-1);
$sqlb = mysql_query("SELECT * FROM banner_pequeno ORDER BY BANNER_ID ASC LIMIT ".$num.",1");
$resultado = mysql_fetch_array($sqlb);
echo "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0' width='192' height='110'><param name='movie' value='$resultado[2]'><param name='quality' value='high'><embed src='$resultado[2]' quality='high' pluginspage='http://www.macromedia.com/go/getflashplayer&#039; type='application/x-shockwave-flash' width='192' height='110'></embed></object>";
?>
26/08/2003 10:30am (~20 anos atrás)

Celso,

ultima coisa

em vez de colocar
$q = "select * from banners";

faça:

$q = "select count(nome_algum_campo) AS total from banners";
$dado = mysql_query($q);
$dado = mysql_fetch_array($dado);
$total = $dado["total"];

pois é muito mais eficiente, imagine se tiver 500 registro de banners!!!!
Você estaria retornando todos!
Você estaria
18/08/2003 9:04am (~20 anos atrás)

Novo Comentário:

(Você pode usar tags como <b>, <i> ou <code>. URLs serão convertidas para links automaticamente.)