Duvida Sobre Select em 3 tabelas - Fórum DevMedia
[id] => 512067
[titulo] => Duvida Sobre Select em 3 tabelas
[date] => 2015-02-26 15:45:53
[Conteudo] => Mostrar as três tabelas "em uma só" não é uma boa prática, e quando é feito, geralmente é feito na linguagem de programação, e não no banco. Mas para fazer o que necessita, tenho uma sugestão que pode ser útil e mais simples, digamos assim.
Já que os dados são "os mesmos", digamos que todos são "pessoas" e cada "pessoa" possui um tipo (Fornecedor, Cliente, Contato). Você pode criar uma tabela de pessoas que se relaciona com a tabela TipoPessoa em um relacionamento.
Ficaria assim se banco:
--Cria  a tabela TipoPessoa
create table TipoPessoa(
IdPessoa int primary key,
Descricao varchar(20))
--Cria a tabela Pessoa
Endereco varchar(200),
Telefone varchar(20),
TipoPessoa int,
FOREIGN KEY (TipoPessoa) REFERENCES TipoPessoa(idPessoa))
--Insere dados na tabela TipoPessoa
insert  TipoPessoa (id, Descricao)values(1,'Fornecedor')
insert  TipoPessoa (id, Descricao)values(2,'Contato')
insert  TipoPessoa (id, Descricao)values(3,'Cliente')
--Insere dados na Tabela Pessoa
insert  pessoa (id, Nome, Endereco, Telefone, TipoPessoa)values(1,'Fulano', 'rua tal', '(xx)xxxx-xxxx', 1)
insert  pessoa (id, Nome, Endereco, Telefone, TipoPessoa)values(2,'Ciclano', 'rua x', '(xx)xxxx-xxxx', 3)
insert  pessoa (id, Nome, Endereco, Telefone, TipoPessoa)values(3,'Beltrano', 'rua y', '(xx)xxxx-xxxx', 2)
insert  pessoa (id, Nome, Endereco, Telefone, TipoPessoa)values(4,'Deltrano', 'rua z', '(xx)xxxx-xxxx', 1)
insert  pessoa (id, Nome, Endereco, Telefone, TipoPessoa)values(5,'Feltrano', 'rua w', '(xx)xxxx-xxxx', 3)
E em sua consulta você buscaria os dados das pessoas, onde a Foreign Key da tabela pessoas for igual ao id da tabela TipoPessoas, ficado assim:
[codeselect t.Descricao, p.Nome, p.Telefone, p.Endereco from Pessoa as p, TipoPessoa as t
where p.TipoPessoa = t.IdPessoa order by t.Descricao;[/code]
E seu resultado seria esse:
[img:descricao=Resultado]http://arquivo.devmedia.com.br/forum/imagem/397347-20150226-154649.png[/img]
Assim você normaliza seu banco, e quando for codificar a aplicação, deixa mais fácil.
Duvida Sobre Select em 3 tabelas
SQL ServerOracleMySQLFirebird
- 26 fev 2015
Estou com duvida de como fazer um select em 3 tabelas diferentes.
A primeira é Contatos com os campos NOME_CONTATO, FONE, ENDERECO.
A segunda é Clientes com os campos NOME_CLIENTE, FONE1, ENDERECO.
A terceira é Fornecedores com os campos NOME_FORNECEDOR, FONE, ENDERECO.
Eu queria trazer os campos NOME, FONE, ENDERECO de cada tabela.
NOME FONE ENDERECO
José XX-XXXXX-XXXX RUA X da Tb Contatos
garfica x XX-XXXXX-XXXX RUA A da Tb Fornecedor
João XX-XXXXX-XXXX Av. X da TB Clientes
Como é que ficaria esse select?
Mostrar as três tabelas "em uma só" não é uma boa prática, e quando é feito, geralmente é feito na linguagem de programação, e não no banco. Mas para fazer o que necessita, tenho uma sugestão que pode ser útil e mais simples, digamos assim.
select t.Descricao, p.Nome, p.Telefone, p.Endereco from Pessoa as p, TipoPessoa as t
where p.TipoPessoa = t.IdPessoa order by t.Descricao;
select a.Nome,a.fone,a.endereco,b.Nome,b.fone,b.endereco,c.Nome,c.fone,c.endereco,	--- coloquei todos dos campos das tabelas ai vc filtra o que achar melhor
from tb_contatos a left join
Tb_Fornecedor b on b.fone = a.fone left join
TB_Clientes c on c.fone = a.fone
--- fiz com base no sql e nao coloquei no management para conferir o codigo se tiver algum erro informar que tento ajudar..
--obs o campo fone nao é o melhor campo para fazer comparação alias nenhum desses campos que vc tem sao campos ideais para comparação devido a questao de performace
se tiver campos unicos e inteiros entre as tabelas faça a comparação com eles ..
Nome_Cliente ---------- FONE --------- ENDERECO ---------------NOME FORMECEDOR
eu queria que ficasse Assim
NOME ---------------------------------FONE -----------------//////////----- EMDERECO
Fornecedor 1 ---------------------- xxxxxxxxxxxx ---------------------- RUA X
Fornecedor 2 ---------------------- xxxxxxxxxxxx ---------------------- RUA X
Cliente 1----------------------------- xxxxxxxxxxxx ---------------------- RUA X
Contato1 ---------------------------- xxxxxxxxxxxx ---------------------- RUA X
Cliente 2 ---------------------------- xxxxxxxxxxxx ---------------------- RUA X
Cliente 3 ---------------------------- xxxxxxxxxxxx ---------------------- RUA X
Fornecedor4----------------------- xxxxxxxxxxxx ---------------------- RUA X
Sera que tem Como ?
amigo vc pode pegar tudo de todas as tabelas colocando inner join no lugar de left join...
mais tem que ver o que vc quer direito... o campo nome vc tem fornecedor, cliente e contato nao entendi o sentido disso.
Isso é para fins didático? Cliente, fornecedor e contato possui os mesmos campos?
Fins Didáticos Sim.
Clientes, Fornecedor e contatos
o campo nome é e diferente NOME_CLIENTE, NOME_FORNECEDOR, NOME_CONTATO
o campo telefone e endereço eu fiz igual e ficou FONE e ENDERECO
Sua pergunta não é muito clara...
Você deseja relacionar registros de Fornecedores, Clientes e Contatos que tenham alguma relação lógica entre si ?
Você deseja apenas unir os selects de tabelas que tem a mesma estrutura ?
Se for pra relacionar essas tabelas, será necessário criar uma estrutura de chaves primárias e estrangeiras para isso... nesse sentido a dica do "Randrade" é perfeita !
Se a ideia for apenas listar tudo...como as tabelas tem uma mesma estrutura ( Nome, Fone e Endereco ) o operador UNION do select resolve...
Tente algo, como :
Select NOME_CONTATO as Nome, FONE as Fone, ENDERECO as Endereco from Contatos
Select NOME_CLIENTE as Nome, FONE1 as Fone, ENDERECO as Endereco from Clientes
Select NOME_FORNECEDOR as Nome, FONE as Fone, ENDERECO as Endereco from Fornecedores
Caso não funcione você deverá ter os mesmos nomes das colunas nas três tabelas.
Captou ?!?
- 27 fev 2015
Sim Vou fazer aqui!
Gostei da solução apresentada pelo Randrade, pois eu acho que é a forma mais correta de manter esses dados.
Não faz sentido ter as tabelas CLIENTE, CONTATO e FORNECEDOR, pelos seguintes motivos:
- Um cliente também pode ser um contato e um fornecedor.
- Um fornecedor também pode ser um cliente e um contato.
- Um contato também pode ser um fornecedor e um cliente.
Então, a melhor forma de manter os dados é como o Randrade sugeriu.
Marisiana,
A solução postada pela Randrade simplesmente agrupa os dados em uma tabela e não evita que "pessoas" que tenham mais de uma perfil apareçam mais de uma vez na tabela ( com "tipopessoa" diferentes ).
É exatamente a mesma situação de ter três tabelas separadas, onde a identificação ocorre pelo tipo de tabela.
Se houvesse uma chave comum nas três tabelas originais ( CPF, por exemplo ), seria simples relacionar as pessoas que tem ocorrências na três tabelas.
Outro modo... seria criar uma tabela única de "pessoa" e uma tabela com o "tipopessoa", de modo a implementar um relacionamento 1:N. Do ponto de vista de normalização de dados, isso seria um passo adiante da solução do Randrade.
Uma definição um pouco mais clara do que realmente o Eduardo precisa, pode nos ajudar a ajudá-lo...
fiz da forma que o Marcos P sugeri o pois a tabela já estava pronta. ficou muito bom e como eu realmente pretendia.
vou tentar me aperfeiçoar mais em comando sql.
Mas quando usa 3 tabelas você acaba duplicando ou triplicando uma mesma informação...
Não penso que é a mesma situação e acho inviável criar 3 tabelas.
Como você vai tratar uma movimentação de vendas, por exemplo? Vai criar 3 Foreign Keys na tabela que mantem os registros de vendas?
segue site que ira ajudar nas suas duvidas http://guiadba.com.br/
Assim como acaba duplicando ou triplicando na mesma tabela, na estrutura proposta pelo Randrade.
O exemplo indicado pelo Eduardo é parcial, pois nem mesmo a estrutura de chaves primárias está definida nessas tabelas.
Sendo assim, temos somente suposições em todos esses cenários.
Quanto a questão das vendas... se aplicam vendas a contatos e fornecedores ?
Vendas, a princípio, aplicam-se a clientes, e portanto, faria sentido relacioná-las apenas a tabela de Clientes.
Estamos supondo uma série de coisa aqui, que não temos condições de definir.
O que é óbvio, contudo, é que apenas a normalização do modelo de dados a partir do cenário real de uso, é a solução ideal para esse caso.
Na verdade, isso não importa muito mais, porque a necessidade do Eduardo era apenas unir três selects via operador union...
Ah sim, no modelo do Randrade, teria que criar o relacionamento 1:N para que uma pessoa possa ser vinculada a mais de um "tipopessoa".
Eu penso que importa, pois o Eduardo mencionou que é para fins didáticos e sabemos que o modelo que ele apresentou não está normalizado.