+6

PHP e MySQL - JOINS em 2 tabelas ou mais

criado por Michael Colla em 06/11/2008 9:37am
A solução para este problema? Utilizando o JOIN do MySQL.
Veja como ficaria o exemplo acima, mas agora otimizado.



Com uma única consulta, temos os resultados. Deixamos o código mais enxuto, evitamos redundâncias e o desempenho será outro com certeza, lembrando do exemplo acima, se 9 usuários realizassem uma consulta com 30 resultados, apenas 9 consultas nos trariam o que precisamos contra as 540 do script inicial.

Vamos entender melhor a consulta com o JOIN.



Na linha 1, definimos quais campos queremos no resultado, a diferença de uma consulta simples, é que vamos apelidar as tabelas, para ficar uma consulta mais enxuta e de fácil compreensão. No nosso exemplo apelidei as tabelas com a 1º letra do nome (p - tabela produto, u - tabela usuário, e - tabela uf, usei e lembrando de estado), mas vc pode usar qualquer apelido que quiser. O último campo, usamos uma formatação para exibir a data no formato dd/mm/aaaa, já que por padrão geralmente se utiliza no formato aaaa/mm/dd.

Na linha 2, informo a 1º tabela, que formará o resultado, é interessante sempre seguir a ordem do select pra que não se confunda quando a consulta for muito grande. Chamo a atenção para a ultima letra desta linha. É assim que apelidamos a tabela pedidos que está dentro do banco de dados clientes, podemos apelidar também desta forma "FROM clientes.pedidos AS p", mas como fiz ja deixa o código mais "clean", pois toda vez que precisar fazer referência à tabela, utilizo o seu apelido, por exemplo, p.nome_do_campo, ao invés de clientes.nome_do_campo.

Na linha 3 começamos a brincar com o JOIN, que podemos entender como "juntar". Então, vou juntar ao resultado o campo e.uf (informado na linha 1), indico que a tabela está no banco de dados base(base.uf), e logo apelido a tabela com o "e". Preciso ter um campo que faça referência entre a tabela de pedidos e a tabela uf, para que traga a sigla correta, é aí que usamos o ON, que seria "onde" e.id (campo id na tabela uf) for igual a p.id_uf (campo id_uf na tabela pedidos). Assim, não será exibido qualquer sigla, somente a do id selecionado.

Finalizando, na linha 4, juntamos ao resultado o campo u.nome que está na tabela usuario dentro do banco de dados base, mesmo esquema, logo depois do nome da tabela, apelidamos ela com "u", onde u.id (campo id na tabela usuario) for igual a p.id_user (campo id user na tabela produtos), assim será exibido o nome corretamente de acordo com o id da tabela usuario.

Parece complicado, mas não é. Digo de experiência própria. A questão é que tem bastante detalhes, mas realmente não é complicado. Agora que sabemos como funciona o JOIN, vamos brincar um pouco com os resultados.

Queremos saber quantos pedidos o usuário com id 1 realizou:
(logo depois da ultima linha com o JOIN) insira
WHERE p.id_user =1

Ha, mas não sei o id, quero pesquisar pelo nome
WHERE u.nome LIKE '%Michael%'
Neste exemplo usamos o parâmetro like que faz comparações em strings, se vc quiser retornar todos os usuário que iniciem com M, por exemplo coloque o caractere curinga "%" do lado direito da letra inicial do nome (like 'M%'), acima usei o caractere curinga na direita e esquerda, para indicar que em qualquer parte do nome se tiver a palavra Michael, é pra selecionar, outra forma (like '_i%') vai retornar todos os nomes que a letra i for a 2º letra do nome.

Queremos saber quantos pedidos foram realizados nos dias 27 e 28/08/2008 (na tabela de pedidos usei datas entre 26 e 29/08), lembrando do padrão da data, aaaa/mm/dd
WHERE p.data > '2008-08-26' AND p.data < '2008-08-29'

Queremos saber os pedidos por estado, vou usar o id 18 (PR)
WHERE p.id_uf =18
ou pelo nome no estado
WHERE e.uf LIKE '%PR%'

Agora listar os pedidos de HD, no PR, na data 26/08/2008
WHERE p.pedido LIKE '%HD%' AND p.id_uf = 18 AND p.data = '2008-08-26'

Enfim, você pode fazer n combinações de como exibir e/ou filtrar os resultados.

Outro exemplo em que o JOIN é muito útil, queremos saber por exemplo, quantos pedidos por estados foram realizados.
SELECT e.uf, COUNt( p.id ) AS total_pedidos
FROM clientes.pedidos p
JOIN base.uf e ON e.id = p.id_uf
GROUP BY e.uf
Neste exemplo, utilizamos GROUP BY, que agrupa os resultados iguais (no caso a sigla), e exibe 1 por vez, tipo PR 3, SP 2, etc. O COUNT, vai fazer a contagem do id da tabela produtos, assim saberemos quantos pedidos foram realizados

Agora queremos saber quantos pedidos cada usuário realizou
SELECT u.nome, COUNT( p.id ) AS total_pedidos
FROM clientes.pedidos p
JOIN base.usuario u ON u.id = p.id_user
GROUP BY u.nome

É isso aí pessoal!
Espero que possa ajudar alguém, e como é meu 1º artigo, peço desculpa se falei algo que não proceda, e críticas, sugestões e correções (de experientes ou não), serão bem-vindas, para que os próximos sejam melhores, e assim eu possa contribuir, e estar ajudando a comunidade PHP de forma geral! Como diz o ditado "é dividindo que se multiplica conhecimento"!

Um abraço a todos e muito sucesso! Caso eu possa ajudar em dúvidas, envie um comentario aqui.

Comentários:

Mostrando 1 - 10 de 13 comentários
Michael Colla disse:
Olá, estou precisando de ajuda urgente, tenho duas tabelas no MySql e preciso fazer uma consulta na tabela associados através do resultado do login na tabela usuarios, ou seja, esta consulta:
select * from associados where IdAssociado=IdAssocidado(da tabela usuarios que foi logada na pagina de login). Então como resultado deve aparecer todos os dados do associado. Se fosse em delphi, vb, já tinha feito, mas, em php não sei como pegar o parâmetro da pagina de login para enviar para a pagina de consulta da tabela e preencher os dados. Se alguém puder me ajudar eu agradeço e me ponho a disposição a fazer o mesmo. Obrigado.

Alex, bom, é recomendável que você envie o formulário via post, assim, na página que vai consultar, você faz algo semelhante:
$sql = mysql_query("Select * from associados where email=".$POST['login']." AND senha='".$POST['senha']."' LIMIT 1;");
if ($sql){
//usuario encontrado, redireciona p/ index.php, por exemplo
} else {
print "dados não conferem", e redireciona pra login.php
}

Lógico que isso ae tá super simples, sem validação, segurança e tal, mas com esse código vc já consegue logar o usuario.
Dá uma olhada na sessão de scripts do site que tem sistemas de logins completos e funcionais.
Espero ter ajudado!
13/08/2010 3:50pm (~14 anos atrás)

Alex Sander disse:
Olá, estou precisando de ajuda urgente, tenho duas tabelas no MySql e preciso fazer uma consulta na tabela associados através do resultado do login na tabela usuarios, ou seja, esta consulta:
select * from associados where IdAssociado=IdAssocidado(da tabela usuarios que foi logada na pagina de login). Então como resultado deve aparecer todos os dados do associado. Se fosse em delphi, vb, já tinha feito, mas, em php não sei como pegar o parâmetro da pagina de login para enviar para a pagina de consulta da tabela e preencher os dados. Se alguém puder me ajudar eu agradeço e me ponho a disposição a fazer o mesmo. Obrigado.
13/08/2010 2:45pm (~14 anos atrás)

Olá Michael!

Parabéns pelo artigo! Me ajudou muito! Conseguiu esclarecer de forma simples o uso do Join. Parabéns e obrigado!
11/03/2010 9:47am (~15 anos atrás)

Michael Colla disse:
Então ClaudioCR, em PHP é simples, vou usar como exemplo, uma tabela onde você queira os clientes de um estado.
A query seria esta:
SELECT * FROM clientes WHERE clientes.id_estado = 1;
Neste caso, temos um inteiro como parâmetro, então:
SELECT * FROM clientes WHERE clientes.id = $variavel;

Supondo que o parâmetro fosse uma string:
SELECT * FROM clientes WHERE clientes.nome = '".$variavel."';

Espero que tenha ajudado, qualquer coisa estamos ae!
08/02/2010 8:58am (~15 anos atrás)

ClaudioCR disse:
Olá, estou procurando e ainda não encontrei.
Postei minha duvida no mysql.com, mas ateh agora ninguém me respondeu.
Não foge muito do tema deste post.
E se os valores fossem inseridos via variãvel? Como uso o % com $variavel? Ex:
"LIKE '%$atividade%'"
Para ver o post no mysql.com o link:
http://forums.mysql.com/read.php?52,325108,325108#msg-325108
07/02/2010 1:36pm (~15 anos atrás)

Michael Colla disse:
Olá Amanda, obrigado por seu comentário. Espero que possa te ajudar na resolução da sua dúvida.
Assumindo que temos uma tabela de disciplinas, e que nessa tabela temos um campo, vamos chamá-lo de id_disciplina, que vem a ser um campo único que vai representar cada uma das disciplinas.
Já na tabela professores, teremos também um campo único que será a identificação dos professores, que vamos chamá-lo de id_professor.
Bom, agora temos que entender uma coisa. Nos banco de dados, existe algo chamado relacionamentos, que nada mais é do que ligações, entre 2 ou mais tabelas. Temos 3 tipos de relacionamentos: um para um, um para muitos e muitos para muitos. Só vou explicar a respeito do muitos para muitos, que é o nosso caso. Quando há um relacionamento assim entre 2 tabelas, não podemos interligá-las diretamente. Veja, pra ficar fácil, vamos supor que temos 3 disciplinas, e 5 professores. Os 2 primeiros professores, lecionam a disciplina 1 e 2. Já os ultimos 3 professores, lecionam a disciplina 3. Não tem como definir isso, diretamente entre essas 2 tabelas. Então, quando há esse tipo de relacionamento, temos que criar uma tabela associativa. Que nada mais é do que uma tabela, onde cada registro vai armazenar o id do professor e o id da disciplina que leciona. Assim, vc pode ter 50 ou quantos professores forem necessários que lecione na determinada determinada disciplina. A nossa vai se chamar leciona_disciplina.
Assim, montamos a seguinte query:

SELECT d.nome
FROM disciplinas d
JOIN leciona_disciplina lec ON lec.id_disciplina = d.id_disciplina
JOIN professores p ON p.id_professor = lec.id_professor
WHERE lec.id_professor =2

Nessa consulta, serão listados todas as disciplinas que o professor com o id 2 leciona.

Qualquer dúvida, é só falar!
28/10/2009 10:49am (~15 anos atrás)

Amanda disse:
adorei o artigo.

estou criando uma pauta eletronica na qual, quando o professor se logar deverá aparecer SOMENTE AS DISCIPLINAS QUE ELE DÁ AULA. gostaria de saber como se faz isso.
desde já agradeço a colaboração.
28/10/2009 3:18am (~15 anos atrás)

Muito bom seu artigo.
Já sabia como fazer JOINS, mas tive bastante dificuldade em aprender por falta de explicações legais como essa.

E faço como o Joelson postou, é a mesmo por menos.

Valeu.
01/10/2009 2:27pm (~15 anos atrás)

Muito bom, com esse artigo eu aprendi a usar o JOIN.

Agora falta eu aprender Select aninhado.
21/07/2009 12:46am (~15 anos atrás)

Michael Colla disse:
Zariel, fico contente em saber que o artigo foi útil pra você!

Joelson, obrigado pelo complemento, realmente eu não conhecia essa forma de junção. Mas prefiro utilizar o JOIN a modelo que exemplifiquei no artigo, pensando na manutenção do sistema. Fica mais fácil identificar quem é quem, ainda mais se você tiver junção com 3 ou mais tabelas.

Valeu!



19/06/2009 8:37am (~15 anos atrás)

Novo Comentário:

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