Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

P3rukao

SELECTS aninhados

Recommended Posts

Galera...

estou tentando fazer uma listagem de dados organizadas por grupos em mais de uma tabela... e estou com dúvida quanto ao número de comandos SELECT a se fazer...

 

Eu tenho as seguintes tabelas:

 

-> usuarios: id, nome, categoria (guarda o id da categoria), estado (guarda o id do estado), cidade (guarda o id da cidade), etc...;

-> categoriaUsuarios: id, nome;

-> usuarios_categorias: usuario_id, categoriausuario_id;

-> estados: id, uf, nome;

-> cidades: id, estado, uf, nome;

 

O que quero fazer é fazer uma listagem de usuarios de uma determinada categoria dentro de um Estado, e dentro deste uma listagem de usuarios dentro de cada Cidade deste Estado, ficando assim:

 

+ Usuarios da categoria [b]3[/b] pertencentes a São Paulo (20):
----- Campinas (10);
----- Ribeirão Preto (2);
----- Paraguaçu Paulista (8);

+ Usuarios da categoria [b]3[/b] pertencentes ao Rio Grande do Norte (10):
----- Natal (3);
----- Mossoró (7);

A query que eu montei, a princípio, foi essa:

 

SELECT u.id AS uid,
 u.categoria AS ucat,
 u.estado AS ue,
 u.cidade AS ucid,
 e.id AS eid,
 e.nome AS en,
 c.id AS cid,
 c.usuarios AS u 
 JOIN estados AS e
 ON (u.estado = e.id)
 JOIN cidades AS c
 ON (c.id = u.cidade)
GROUP BY e.id

Mas queria saber como fazer para montar o contador de usuarios, e se pra cada estado listado nessa ultima consulta, eu teria de fazer outra consulta pra listar os usuarios de cada cidade desse estado, ou se isso poderia ser feito num unico comando utilizando mais JOINS???

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu consegui fazer funcionar aqui porém ele está fazendo muitas consultas ao banco...

 

<?
	$categoria = 3;
	$se = " 
		SELECT u.id AS uid,
				u.categoria AS ucat,
				u.estado AS ue,
				u.cidade AS ucid,
				e.id AS eid,
				e.nome AS en,
				c.id AS cid,
				c.nome AS cn
		 FROM "._USUARIOS." AS u 
			JOIN "._ESTADOS." AS e
			 ON (u.estado = e.id)
			JOIN "._CIDADES." AS c
			 ON (c.id = u.cidade)
		 WHERE u.categoria = '".$categoria."'
		 GROUP BY eid
	";	 
			 
	$qe = mysql_query($se) or die(mysql_error());
	if(mysql_num_rows($qe)>0){
		$i=0; $j=0;
		while($re = mysql_fetch_array($qe)){
			$estado[$i] = $re;
			
			$contE = " 
				SELECT *
				 FROM "._USUARIOS." AS u 
				 JOIN "._ESTADOS." AS e
					ON (u.estado = e.id)
				 WHERE u.estado = '".$re['eid']."'
			";
			$qcontE = mysql_query($contE) or die(mysql_error());//numero de usuarios dentro do estado
			$numE[$i] = mysql_num_rows($qcontE);

			$sc = " 
				SELECT c.id AS cid,
					 c.nome AS cn,
					 u.estado AS ue
				 FROM "._CIDADES." AS c
				 JOIN "._USUARIOS." AS u
					ON (c.id = u.cidade)
				 WHERE c.estado = '".$re['eid']."'
			 GROUP BY cid
			";			
			$qc = mysql_query($sc) or die(mysql_error());
			while($rc = mysql_fetch_array($qc)){
				$cidade[$j] = $rc;
				
				$contC = " 
					SELECT *
					 FROM "._USUARIOS." AS u 
					 JOIN "._CIDADES." AS c
						ON (u.estado = c.id)
					 WHERE u.cidade = '".$rc['cid']."'
				";
				$qcontC = mysql_query($contC) or die(mysql_error());//numero de usuarios dentro de cada cidade dentro do estado atual
				$numC[$j] = mysql_num_rows($qcontC);
				
				$j++;
			}
			
			$i++;
		}//end while estados

		//echo "<h4>NUMERO DE USUARIOS DE CADA ESTADO</h4><pre>", print_r($numE), "</pre>";
		//echo "<h4>NUMERO DE CIDADEs</h4><pre>", print_r($numC), "</pre>";
		//echo "<h4>ESTADOS</h4><pre>", print_r($estado), "</pre>";
		//echo "<h4>CIDADES</h4><pre>", print_r($cidade), "</pre>";
		
		/*foreach($estado as $v){
			echo $v['en']."<br / > ";
		}*/

		foreach($estado as $k => $v){
			echo "<div>",
			"<h3>", $estado[$k]['en'], $estado[$k]['eid'], " (".$numE[$k].")", "</h3>",
			"<ul class=\"listaEstados\">";
			foreach($cidade as $k => $v){
				echo "<li>",$cidade[$k]['cn'],$cidade[$k]['ue'], " (".$numC[$k].")", "</li> ";
			}
			echo "</ul></div>";
		}
	}
	else echo "nenhum estado";
?>

 

O problema que está acontecendo é que ao listar as cidades de cada estado... ele está listando a dos estado restantes também... mesmo usando a clausula WHERE...

Alguém sabe onde está o problema???

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olha, vou te dar a lógica. Você vai usar só uma consulta e vários ifs.

 

A sua consulta deve retornar algo assim...

 

Categorias - Estado --- Cidade - Usuario

3 -------- São Paulo -- Campinas - 10

3 -------- São Paulo -- Ribeirão - 8

3 -------- São Paulo -- Paraguaçu - 1

3 -------- Rio Grande -- Natal - 1

3 -------- Rio Grande -- Mossoró - 1

 

Aí, você faz algo assim para exibir.

$estado = '';
while ($row = mysql_fetch_assoc($sql))
{
    if($row['estado'] != $estado)
    {
         echo ' Usuário da categoria '.$row['categoria'].' pertencentes ao estado '.$row['estado'];
         $estado = $row['estado'];
    }
    if($row['cidade'] != $cidade)
    {
         echo '<br/>---'.$row['cidade'];
         $cidade = $row['cidade'];
    }
    echo $row['usuario'];
}

O que vai acontecer. Na primeira vez do while, vai exibir a mensagem do estado e da categoria. Na segunda iteração, se o estado for o mesmo, só vai exibir a cidade e o usuário. Se for diferente, vai exibir a mensagem.

 

Carlos Eduardo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bacana Matias... eu passei exatas 9horas matutando aqui como fazer isso mas só fiz foi aumentar cada vez mais as consultas... mas deu certinho essa tua lógica (eu tava quase lá :P)

 

Brigadão aew...

 

Agora, para colocar o contador que mencionei... tem como ser na instrução do mysql com um COUNT(*) ou PARA ISSO eu faço outra consulta?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olha, aí é melhor perguntar no fórum de Mysql. Vou mover pra lá que o pessoal te ajuda.

 

Carlos Eduardo

 

Tópico Movido

PHP http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Mysql

Compartilhar este post


Link para o post
Compartilhar em outros sites

Como está o teu script agora, e as consultas no momento ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

A minha ultima versão eh a do post número DOIS... mas depois da dica do Matias eu tentei alterar umas coisas aqui para poder manipular melhor a exibição dos resultados.

Eu estou tentando organizar melhor a exibição dos dados inserindo cada resultado num HTML específico e no momento está assim:

 

$categoria = 3;
$se = " 
	SELECT u.id AS uid,
			u.categoria AS ucat,
			u.estado AS ue,
			u.cidade AS ucid,
			e.id AS eid,
			e.nome AS en,
			c.id AS cid,
			c.nome AS cn
	 FROM "._USUARIOS." AS u 
		JOIN "._ESTADOS." AS e
		 ON (u.estado = e.id)
		JOIN "._CIDADES." AS c
		 ON (c.id = u.cidade)
	 WHERE u.categoria = '".$categoria."'
	 ORDER BY eid
";	 
		 
$qe = mysql_query($se) or die(mysql_error());
if(mysql_num_rows($qe)>0){
	
	$i=0;$j=0;
	while ($row = mysql_fetch_array($qe))
	{
		$estado[$i] = $row;
		$i++;
	}
	
	foreach($estado as $k => $v){
		
		if($estado[$k]['eid'] != $estados['id'])
		{
			 $estados[$k]['id'] = $estado[$k]['eid'];
			 $estados[$k]['nome'] = $estado[$k]['en'];
		}
		
		if($estado[$k]['cid'] != $cidades['id'])
		{
			 $cidades[$k]['eid'] = $estado[$k]['eid'];
			 $cidades[$k]['cid'] = $estado[$k]['cid'];
			 $cidades[$k]['cn'] = $estado[$k]['cn'];
		}
	}
	
	$i=0;$j=0;
	foreach($estados as $e){
		if($estados[$i]['id'] != $estado)
		{
			$estado = $estados[$i]['id']; 
			echo 
			"<div class=\"listaEstados\">\n",
			"<h1 class=\"roundAll\">",$estados[$i]['nome'],"</h1>\n",
			"<ul>";
			foreach($cidades as $c){
				if($cidades[$j]['eid'] == $estados[$i]['id']){
					echo "<li><a href=\"#\">",$cidades[$j]['cn'], "</a></li> \n";
					$j++;
				}
			}
			echo 
			"</ul>",
			"<br clear=\"all\" />",
			"\n</div>\n";
		}
		$i++;
	}
}
else echo "nenhum estado";

 

Está funcionando direitinho, Graças a dica do Matias, mas ainda resta bolar um contador...

mas creio que isso seja com PHP mesmo... ou tem como já pegar isso na consulta mysql de primeira?

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.