CONSULTA SQL - 2 TABELAS

11/03/2016

Pessoal, boa tarde!

Em um sistema antigo, era exibido uma tabela onde mostrava os dados de todos os clientes no banco de dados(Tabela:cli_clientes) e para cada linha de cliente mostrava uma coluna com a data do ultimo contato realizado para esta empresa (Tabela: tel_historico), ou seja, na tabela de historico poderia ter varios contato com a mesma empresa mas exibia somente o mais recente.

[img:descricao=Modelo Banco de Dados]http://arquivo.devmedia.com.br/forum/imagem/442530-20160311-160402.jpg[/img]


O codigo utilizado pelo sistema antigo é:


$query = mysql_query("SELECT cli_codigo, cli_nome, cli_cidade
  FROM cli_clientes
  WHERE cli_nome LIKE '%".$_GET['cli_nome']."%' AND cli_cidade LIKE %".$_GET['cidade']."%' AND cli_vinculo LIKE '%".$_GET['vinculo']."%'");
  
  while($mostrar = mysql_fetch_array($query)){

      $result_historico = mysql_query("SELECT tel_status, tel_datacontato, tel_horacontato
        FROM tel_historico WHERE cli_codigo = '".$mostrar['cli_codigo']."'
        ORDER BY `tel_historico`.`tel_codigo` DESC,`tel_historico`.`tel_datacontato` DESC, `tel_historico`.`tel_horacontato` DESC LIMIT 0 , 1");
        
        $row_historico = mysql_fetch_array($result_historico);

       <table>
       <tr><td></td>td></td>td></td></tr>
       <tr><td></td>td></td>td></td></tr>
   }
    


Obsservem que pego todos os clientes utilizando WHILE e ao mesmo tempo já vou pegando através de outro SELECT o ultimo contato realizado para o cliente da vezs no WHILE, ou seja, o WHILE esta pegando o cliente 1 mostrando o seus dados e para completar a informação, consulta a o historico pegando o ultimo contato realizado com o cliente do mesmo codigo (1)



Estou alterando a tabela de exibição e usando datagrid chamado Bootgrid, e o mesmo utiliza o código abaixo para enviar as informação para tabela:

$sql = "SELECT cli_codigo, cli_nome, cli_bairro, cli_cidade FROM cli_clientes {$where} ORDER BY {$order_by} {$limit}";

$stmt = $conn->prepare($sql);
$stmt->execute();
				
$results_array = $stmt->fetchAll(PDO::FETCH_ASSOC);


Observem o WHERE, ORDER BY e o LIMIT, são variaveis que recebem valores de acordo com a pesquisa, ordenação e limite que o usuário final insere na tabela


O grande problema que não consigo fazer isto, pois não posso substituir o WHERE, ORDER BY e o LIMIT padrão do codigo, não sei como exibir da mesma forma que a tabela anterior nesta.

Cristiano Henrique

Melhor resposta

11/03/2016

Escrevi novamente baseado no seu antigo, não sei se é essa sua dúvida:
$sql = "SELECT cli_codigo, cli_nome, cli_bairro, cli_cidade FROM cli_clientes {$where} ORDER BY {$order_by} {$limit}";
$stmt = $conn->prepare($sql);
$stmt->execute();       
$clientes = $stmt->fetchAll(PDO::FETCH_OBJ);

foreach($clientes as $cliente):

	$sql = "SELECT tel_status, tel_datacontato, tel_horacontato FROM tel_historico ";
	$sql .= "WHERE cli_codigo = {$cliente->cli_codigo} ";
	$sql .= "ORDER BY tel_historico.tel_codigo DESC, tel_historico.tel_datacontato DESC, tel_historico.tel_horacontato DESC LIMIT 0 , 1";
	$stmt = $conn->prepare($sql);
	$stmt->execute();       
	$clientes = $stmt->fetchAll(PDO::FETCH_OBJ);

endforeach;

William (devwilliam)

Responder Citar

Outras Respostas

11/03/2016

Cristiano Henrique

Willian,
Obrigado por responder!

Seu código ajudou muito, mas acontece que na variável final deve se usar fetchAll(PDO::FETCH_ASSOC) e dentro desta variavel deve estar tanto os dados dos clientes como do historico(data ultima ligação)

ex.

cli_codigo (Cliente)
cli_nome (Cliente)
cli_bairro (Cliente)
cli_cidade (Cliente)
tel_datacontato (Historico) - Contendo apenas um registro do cliente e sempre o ultimo(Mais recente).


No seu codigo, avariavel final no var_dump so esta me mostrando a data do ultimo contato no array.
Responder Citar

11/03/2016

William (devwilliam)

Certo, vamos ver se agora vai rsrs
$sql = "SELECT c.cli_codigo, c.cli_nome, c.cli_bairro, c.cli_cidade, MAX(h.tel_datacontato) "; 
$sql .= "FROM cli_clientes c INNER JOIN tel_historico h ON c.cli_codigo = h.cli_codigo  {$where} ORDER BY {$order_by} {$limit}";
$stmt = $conn->prepare($sql);
$stmt->execute();       
$clientes = $stmt->fetchAll(PDO::FETCH_OBJ);
 
foreach($clientes as $cliente):

 
endforeach;


O estilo do fetch vc vê qual é o melhor, por default já é Associativo e Indexado com número.

Observação, não esqueça de colocar o alias "c" nos campos da condição WHERE que forem da tabela cli_clientes!
Responder Citar

14/03/2016

Cristiano Henrique

Oi Willian,

Desta vez ele me retornou apenas um registro, veja como ficou o codigo:

$sql = "SELECT c.cli_codigo, c.cli_nome, c.cli_bairro, c.cli_cidade, MAX(h.tel_status) "; 
$sql .= "FROM cli_clientes c INNER JOIN tel_historico h ON c.cli_codigo = h.cli_codigo ORDER BY {$order_by} {$limit}";
$stmt = $conn->prepare($sql);
$stmt->execute();       
$results_array = $stmt->fetchAll(PDO::FETCH_ASSOC);

                $pack		         	= array();
		$pack["current"] 		= $current;
		$pack["rowCount"] 		= $rowCount;
		$pack["rows"]			= $results_array;
		$pack["total"]			= $nRows;



E mesmo assim aida tive que retirar o para aparecer....

Estou perdendo as esperanças viu, coisa que parecia até fácil mas....

Tem outra sugestão?
Responder Citar

14/03/2016

William (devwilliam)

Mas está usando qual valor na clausula "LIMIT"?
Responder Citar

14/03/2016

Cristiano Henrique

Na exibição da tabela, o valor padronizado é 10 por página, onde pode alterar para 25, 50 ,100...
Se eu tirar o {$limit} da query, ele continua aparecendo somente 1 registro , aperecendo somente os dados da empresa, sem a data do ultimo contato (Tabela historico)

O criterio usado para exibir a empresa é totalmente estranho, não foi por data, não foi pelo nome da empresa e nem por codigo...
Responder Citar

14/03/2016

William (devwilliam)

Não é um SELECT complexo, teoricamente seria para funcionar, o problema é escrever sem ter o cenário das tabelas.

Mas vou fazer uns testes aqui!
Responder Citar

14/03/2016

Cristiano Henrique

Concordo com você, mas acredito que o problema esteja na entrega da variável final, que deve ser enviada em fetchAll(FETCH_ASSOC)
e esta variável será encaixada em um array como descrito no ultimo código enviado.
Responder Citar

14/03/2016

Cristiano Henrique

Ok! Segue print resultado:
[img:descricao=Print]http://arquivo.devmedia.com.br/forum/imagem/442530-20160314-133117.png[/img]
[img:descricao=Print]http://arquivo.devmedia.com.br/forum/imagem/442530-20160314-133548.png[/img]
Responder Citar

14/03/2016

Cristiano Henrique

Observe a empresa ROMA PLUS

-Contato mais recente cadastrado no banco = 10/03/2016
-Contato mais antigo cadastrado no banco = 07/08/2012
-Contato exibido com a ultima query que você enviou (corrigida) = 31/03/2014

Se eu mudo a query da seguinte forma

[img]http://arquivo.devmedia.com.br/forum/imagem/442530-20160314-133952.png[/img]:
[img]http://arquivo.devmedia.com.br/forum/imagem/442530-20160314-134006.png[/img]
Responder Citar

14/03/2016

Cristiano Henrique

Willian,

Muito obrigado pela ajuda, o problema foi solucionado!
Te agradeço pela atenção e paciencia rsrs...

Segue código para quem tiver a mesma dúvida:

$sql = "SELECT c.cli_codigo, c.cli_nome, c.cli_bairro, c.cli_cidade, cli_vinculo, MAX(h.tel_datacontato) as tel_datacontato 
                FROM cli_clientes c INNER JOIN tel_historico h ON c.cli_codigo = h.cli_codigo {$where}
                GROUP BY c.cli_codigo, c.cli_nome, c.cli_bairro, c.cli_cidade, cli_vinculo  ORDER BY {$order_by} {$limit}";
        
                $stmt = $conn->prepare($sql);
                $stmt->execute();       
                $results_array = $stmt->fetchAll(PDO::FETCH_ASSOC);
Responder Citar

14/03/2016

William (devwilliam)

Que bom Cristiano, estou finalizando o tópico!
Responder Citar