Duvida Sobre Select em 3 tabelas

26/02/2015

0

Bom Dia!

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.

ficando assim
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?
Eduardo Mendonça

Eduardo Mendonça

Responder

Post mais votado

26/02/2015

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

create table Pessoa(
  Id int primary key,
  Nome varchar(100),
  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.

Randrade

Randrade
Responder

Mais Posts

26/02/2015

Isaac Jose

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 ..

att

Isaac
Responder

26/02/2015

Eduardo Mendonça

Boa tarde!

Aqui ficou assim:

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 ?
Responder

26/02/2015

Isaac Jose

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.
Responder

26/02/2015

Randrade

Boa tarde!

Aqui ficou assim:

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 ?


Isso é para fins didático? Cliente, fornecedor e contato possui os mesmos campos?
Responder

26/02/2015

Eduardo Mendonça

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
Responder

26/02/2015

Marcos P

Eduardo,

Sua pergunta não é muito clara...

Você deseja relacionar registros de Fornecedores, Clientes e Contatos que tenham alguma relação lógica entre si ?
ou
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 
UNION ALL
Select NOME_CLIENTE as Nome, FONE1 as Fone, ENDERECO as Endereco from Clientes
UNION ALL
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 ?!?
Responder

27/02/2015

Eduardo Mendonça

Bom Dia a Todos!

Sim Vou fazer aqui!
Responder

27/02/2015

Marisiana Battistella

Bom dia!
Gostei da solução apresentada pelo Randrade, pois eu acho que é a forma mais correta de manter esses dados.
Responder

27/02/2015

Marisiana Battistella

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.
Responder

27/02/2015

Marcos P

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...

;-)
Responder

27/02/2015

Eduardo Mendonça

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.


Vivendo e aprendendo!


Pode fechar o tópico.
Responder

27/02/2015

Marisiana Battistella

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...

;-)

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?
Responder

27/02/2015

Isaac Jose

segue site que ira ajudar nas suas duvidas http://guiadba.com.br/
Responder

27/02/2015

Marcos P

Marisiana,

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...
Responder

27/02/2015

Marisiana Battistella

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.
Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar