Ir para o conteúdo
joaocasta

Como fazer para aparecer um rank e depois aparecer o meu rank em baixo

Mensagens Recomendadas

joaocasta

Boas pessoal. Já tenho este código que me mostra isto:

1 xxxx 50

2 xxxx 49

3 xxxx 44

4 xxxx 20

5 xxxx 15


<?php
require 'config.php';
$query = mysql_query("SELECT * FROM points ORDER BY `points` DESC");

$i = 0;
while ($row = mysql_fetch_assoc($query)) {
$i++;
echo $i . " ";
echo $row['username'] . " ";
		echo $row['points'] . "<br/>";
	}

?>

O que eu queria que me mostrasse era tipo isto, onde aparecem 5 lugares ou mais e depois em baixo aparece onde eu estou, mas so aparece o de baixo se nao estiver em nenhum dos de cima:

1 xxxx 50

2 xxxx 49

3 xxxx 44

4 xxxx 20

5 xxxx 15

200 xxxx 1

Editado por joaocasta

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
joaocasta

Bem me parecia que não ia conseguir explicar-me. :confused:

É assim eu quero que mostre o TOP 10 MELHORES e depois se eu não estivesse nesses 10 MELHORES iria aparecer o lugar onde eu estava, por exemplo se eu estivesse no 100 lugar ou 200 ou seja lá o que for.

Expliquei-me melhor?

Desculpem o incomodo.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
yoda

Tinha percebido essa parte, mas depois a tua explicação do que estava a acontecer não foi tão clara.

Experimenta isto (testa primeiro a query no phpmyadmin ou algo similar) :

<?php
$user = 1; // imaginando que este é o ID do user actual, ou o teu neste caso
require 'config.php';
$query = mysql_query("SELECT * FROM points LIMIT 5 UNION ALL SELECT * FROM points WHERE user_id = $user ORDER BY `points` DESC");
$i = 0;
while ($row = mysql_fetch_assoc($query)) {
$i++;
echo $i . " ";
echo $row['username'] . " ";
					echo $row['points'] . "<br/>";
			}
?>

Editado por yoda

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

Experimenta isto (testa primeiro a query no phpmyadmin ou algo similar) :

se o resultado estiver no top, irá aparecer após a lista ...

acho que o mais simples (alterando pouco no SQL que apresentaste é fazer o segundo select ter uma negação de projecção no primeiro select.

algo deste género:

select *
 from tbl
limit 5
union
select *
 from tbl
where id = '12'
not in (select *
         from tbl
        limit 5)

desta forma, caso o registo estiver no top, é descartado na projecção NOT IN e não é apresentado na união.

  • Voto 1

IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
joaocasta

yoda não era bem isso que queria.

Happy tentei isso, mas a query nao me retornava nenhum resultado no PHPMyAdmin. Penso que não seja bem assim a query.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
joaocasta

Sim adaptei. Coloquei isto


SELECT *
FROM points
LIMIT 5
UNION
SELECT *
FROM points
WHERE username = 'joaocasta'
NOT IN (SELECT *
FROM points
        LIMIT 5)

Mas não me retorna nada.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

verificaste se o SQL tem erros de sintaxe ? se a execução retorna erro ?

se não retorna erro, e não retorna nada é porque a tabela não tem registos


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
joaocasta

apareceu este erro em baixo na consola.

/* SQL Error (1235): This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' */

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
brunoais

wow what?

Que raio de versão do MySQL é que está a usar?!?!?


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
joaocasta

Acho que é esta.

MySQL client version: mysqlnd 5.0.9-dev - 20110325 - $Revision: 315975 $

Editado por joaocasta

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
brunoais

Atualiza o MySQL para a versão 5.5, no mínimo.

A versão 5.0 já é muito velha (e acho que já n é suportada).


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
brunoais

Depende do OS, depende se usas um package pre-formatado ou não.

Para qualquer um desses casos, a solução é bastante diferente.


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
joaocasta

Mas o problema poderá estar aí?


(select * from points ORDER BY points DESC LIMIT 5)
UNION
(select * from points WHERE username = 'joaocasta')

Tentei com esta query, mas o problema é que diz que eu estou em 6º lugar, mas na realidade estou em 10º.

Será que tenho de trocar alguma coisa na incrementação?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
brunoais

Como é que tens essa tabela formatada?


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
joaocasta

username -> TEXT

points -> INT

multiplied_points -> INT

time -> DATE

É isto que tenho

Editado por joaocasta

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

pensa um bocadito ...

se o query retornar 5 registos então o registo encontrasse no top 5, se retornar 6 porque não está

ter o registo na posição 6 do result set não quer dizer que se encontra na 6ª posição da tabela !!!

eu dei uma solução que necessitava de poucas alterações à proposta do @yoda, não quer dizer que eu teria feito dessa forma.

$sql = "..."; // ler o top 5
$rs = /* ... */; // executar o query

$in_top = false;
foreach ($rs as $record)
{
 /* verificar se o registo se encontra no top 5 */
 if (/* ... */)
 {
   $in_top = true;
 }
 /* apresentar o registo */
}

if (!$in_top)
{
 $sql = "..."; // SQL de ler o registo
 $rs_player /* ... */; // ler o registo da BD

 $player_points = /* ... */;

 $sql = "select count(...) from tbl where points > '$player_points'"; // SQL para saber a verdadeira posição do jogador

 /* ... patati patata ... */
}


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
brunoais

Fazer isso só com 1 query não me parece ser trivial, mas com o UNION já tens o que queres.

O que eu consigo pensar para se conseguir fazer isso só com queries à DB, assim de repente, requer 4 queries.

1 já tens (n a vou explicar).

Precisas de uma subQuery para obter quantos pontos tens.

Precisas de uma query para contar quantos têm pontos maiores/menores (O maior/menor depende do significado da pontuação) que tu.

Precisas de uma query para obter os teus dados e inserir (usando as outras sub-queries) a posição aonde estás.

Vê se com isto consegues descobrir uma boa query para fazeres à DB. Já te dei o pacote todo com os ingredientes, já só falta fazer o sumo.

Editado por brunoais
(O maior ou menor depende do significado da pontuação)

"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
joaocasta

pensa um bocadito ...

se o query retornar 5 registos então o registo encontrasse no top 5, se retornar 6 porque não está

ter o registo na posição 6 do result set não quer dizer que se encontra na 6ª posição da tabela !!!

eu dei uma solução que necessitava de poucas alterações à proposta do @yoda, não quer dizer que eu teria feito dessa forma.

$sql = "..."; // ler o top 5
$rs = /* ... */; // executar o query

$in_top = false;
foreach ($rs as $record)
{
 /* verificar se o registo se encontra no top 5 */
 if (/* ... */)
 {
$in_top = true;
 }
 /* apresentar o registo */
}

if (!$in_top)
{
 $sql = "..."; // SQL de ler o registo
 $rs_player /* ... */; // ler o registo da BD

 $player_points = /* ... */;

 $sql = "select count(...) from tbl where points > '$player_points'"; // SQL para saber a verdadeira posição do jogador

 /* ... patati patata ... */
}

Não percebi bem o codigo.

Fazer isso só com 1 query não me parece ser trivial, mas com o UNION já tens o que queres.

O que eu consigo pensar para se conseguir fazer isso só com queries à DB, assim de repente, requer 4 queries.

1 já tens (n a vou explicar).

Precisas de uma subQuery para obter quantos pontos tens.

Precisas de uma query para contar quantos têm pontos maiores/menores (O maior/menor depende do significado da pontuação) que tu.

Precisas de uma query para obter os teus dados e inserir (usando as outras sub-queries) a posição aonde estás.

Vê se com isto consegues descobrir uma boa query para fazeres à DB. Já te dei o pacote todo com os ingredientes, já só falta fazer o sumo.

Vou tentar, obrigado bruno.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
joaocasta


<?php

function showrank() {
 $sql = "SELECT * FROM points ORDER BY points DESC LIMIT 5"; // ler o top 5
 $rs = mysql_query($sql); // executar o query
 $points = 1;
 $sql2 = "select count(points) AS rank from points where points > '$points'"; // SQL para saber a verdadeira posição do jogador
 $rs2 = mysql_query($sql2);
 $sql3 = "SELECT points FROM points WHERE username = 'estupido'";
 $rs3 = mysql_query($sql3);
 $i=0;
 while ($row = mysql_fetch_assoc($rs)){
   $i++;
   echo $i . " ";
   echo $row['username'] . " ";
		echo $row['points'] . "<br/>";
 }

 while ($row2 = mysql_fetch_assoc($rs2)) {
   while ($row3 = mysql_fetch_assoc($rs3)){
     echo "<b>";
     echo $row2['rank']+1 . " ";
     echo 'estupido ';
     echo $row3['points'];
     echo "</b>";
   }
 }
}
?>

Estou aqui de novo. Este foi o código que consegui fazer e resultou. Mas preciso de saber se há alguma forma de tornar o código mais simples, com menos linhas de código.

Cumps,

Joao.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
brunoais

Não sei como é que isso funciona bem, mas não vejo maneira de fazeres isso com menos de 3 queries, tendo em conta a maneira como tens a DB.


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
brunoais

Depende muito do problam que estás a resolver e não deste sub-problema. Aprende-se mais com experiencia do que outra coisa.

Não te consigo ajudar porque é demasiado complexo para ter tempo para pensar contigo.


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.