Ir para conteúdo

POWERED BY:

Arquivado

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

Alex_ps

[Resolvido] Select em Várias Tabelas com Inner Join e mais...

Recommended Posts

Olá Amigos,

 

Estou desenvolvendo um select que não apresenta erros mas não executa o que eu gostaria.

Solicito a gentileza de uma ajuda para resolver este problema.

Qualquer ajuda é benvinda!

 

Tenho várias tabelas em um banco MYSQL.

Apenas para exemplificar, algumas das tabelas são:

- produtos

- secoes

- categorias

- subcategorias

- modelos

- tamanhos

- etc.

 

No caso, a tabela produtos traz as junções tais como SecaoID, CatId, SubCatID, ModId, etc.

 

Um primeiro problema surge se eu coloco como Inner Join do select algum campo que não tenha sido preenchido em nenhum dos produtos, algo como o modelo. À partir daí o select não funciona.

 

Eu tentei fazer uma pré-filtragem realizando um select externo, primeiramente verificando se algum campo da coluna modelos havia sido preenchido. Assim caso não haja preenchimento, eu não coloco no inner join.

 

Esta alternativa me trouxe a necessidade de mais 6 selects prévios de verificação, o que por si só eu já não sei se é uma boa idéia com relação a desempenho.

 

Outra coisa, aconteceu que, após algumas filtragens, se ao liberar, por exemplo a construção do select com o Inner join da tabela marcas e obtiver a resposta de 4 produtos e depois liberar o inner join da tabela tamanho, o select considera especificamente a conjunção entre as tabelas e não a soma entre as tabelas. Com isto, os produtos que eram 4, caem para 2 por exemplo, mas que na realidade o termo buscado era uma marca e não um tamanho.

 

O código segue abaixo para facilitar o entendimento.

 


  '*** Recupero a informação buscada
  Dim busca : busca = request("busca")

  '*** Verifico se as colunas da tabela de produtos estão sendo utilizadas.
  '*** Com base nestas respostas é que vou montar o Select de Inner Joins
  Dim SqlMod, RsMod
  SqlMod = "Select ModId from tbl_produtos where Length(ModId) > 0 "
  Set RsMod = Conn.execute(SqlMod)

  Dim SqlTam, RsTam
  SqlTam = "Select TamId from tbl_produtos where Length(TamId) > 0"
  Set RsTam = Conn.execute(SqlTam)

'   Dim SqlCor, RsCor
'   SqlCor = "Select CorId from tbl_produtos where CorId <> ''"
'   Set RsCor = Conn.execute(SqlCor)

'   Dim SqlFab, Rsfab
'   SqlFab = "Select FabId from tbl_produtos where FabId <> ''"
'   SqlFab = "Select FabId from tbl_produtos where FabId is not null"
'  Set RsFab = Conn.execute(SqlFab)

'   Dim SqlUnid, RsUnid
'   SqlUnid = "Select UnidId from tbl_produtos where UnidId <> ''"
'   SqlUnid = "Select UnidId from tbl_produtos where UnidId is not null"   
'   Set RsUnid = Conn.execute(SqlUnid)

  '*** Declaro variáveis para realizar a busca
  Dim SqlSearch, RsSearch

  '*** Inicio a string SQL
  SqlSearch = SqlSearch & "Select * from ((("

  '*** Verifico se a coluna 'ModId' da tabela 'tbl_produtos está preenchida - se estiver acrescento este trecho na string
  If not RsMod.Eof then : SqlSearch = SqlSearch & "(" : End If

  '*** Verifico se a coluna 'TamId' da tabela 'tbl_produtos está preenchida - se estiver acrescento este trecho na string
  If not RsTam.Eof then : SqlSearch = SqlSearch & "(" : End If

  '*** Verifico se a coluna 'CorId' da tabela 'tbl_produtos está preenchida - se estiver acrescento este trecho na string
'   If not RsCor.Eof then : SqlSearch = SqlSearch & "(" : End If

  '*** Verifico se a coluna 'FabId' da tabela 'tbl_produtos está preenchida - se estiver acrescento este trecho na string
'   If not RsFab.Eof then : SqlSearch = SqlSearch & "(" : End If

  '*** Verifico se a coluna 'UnidId' da tabela 'tbl_produtos está preenchida - se estiver acrescento este trecho na string
'   If not RsUnid.Eof then : SqlSearch = SqlSearch & "(" : End If

  SqlSearch = SqlSearch & "tbl_produtos Inner Join tbl_secoes On tbl_produtos.SecaoId = tbl_secoes.SecaoId) "
  SqlSearch = SqlSearch & "Inner Join tbl_categorias On tbl_produtos.CatId = tbl_categorias.CatId) "
  SqlSearch = SqlSearch & "Inner Join tbl_subcategorias On tbl_produtos.SubCatId = tbl_subcategorias.SubCatId) "

  '*** Verifico se a coluna 'ModId' da tabela 'tbl_produtos está preenchida - se estiver acrescento este trecho na string
  If not RsMod.Eof then : SqlSearch = SqlSearch & "Inner Join tbl_modelos On tbl_produtos.ModId = tbl_modelos.ModId) " : End If

  '*** Verifico se a coluna 'TamId' da tabela 'tbl_produtos está preenchida - se estiver acrescento este trecho na string
  If not RsTam.Eof then : SqlSearch = SqlSearch & "Inner Join tbl_tamanhos On tbl_produtos.TamId = tbl_tamanhos.TamId) " : End If

  '*** Verifico se a coluna 'CorId' da tabela 'tbl_produtos está preenchida - se estiver acrescento este trecho na string
'   If not RsCor.Eof then : SqlSearch = SqlSearch & "Inner Join tbl_cores On tbl_produtos.CorId = tbl_cores.CorId) " : End If

  '*** Verifico se a coluna 'FabId' da tabela 'tbl_produtos está preenchida - se estiver acrescento este trecho na string
'   If not RsFab.Eof then : SqlSearch = SqlSearch & "Inner Join tbl_fabricantes On tbl_produtos.FabId = tbl_fabricantes.FabId) " : End If

  '*** Verifico se a coluna 'UnidId' da tabela 'tbl_produtos está preenchida - se estiver acrescento este trecho na string
'   If not RsUnid.Eof then : SqlSearch = SqlSearch & "Inner Join tbl_unidades On tbl_produtos.UnidId = tbl_unidades.UnidId) " : End If

  SqlSearch = SqlSearch & "where tbl_produtos.ProdNome like '%"&busca&"%' "
  SqlSearch = SqlSearch & "or tbl_produtos.ProdDescricao like '%"&busca&"%' "
  SqlSearch = SqlSearch & "or tbl_produtos.ProdVolt like '%"&busca&"%' "
  SqlSearch = SqlSearch & "or tbl_produtos.ProdCodBarra like '%"&busca&"%' "
  SqlSearch = SqlSearch & "or tbl_produtos.ProdRegistro like '%"&busca&"%' "   
  SqlSearch = SqlSearch & "or tbl_secoes.SecaoNome like '%"&busca&"%' "
  SqlSearch = SqlSearch & "or tbl_categorias.CatNome like '%"&busca&"%' "
  SqlSearch = SqlSearch & "or tbl_subcategorias.SubCatNome like '%"&busca&"%' "

  '*** Verifico se a coluna 'ModId' da tabela 'tbl_produtos está preenchida - se estiver acrescento este trecho na string
  If not RsMod.Eof then : SqlSearch = SqlSearch & "or tbl_modelos.ModNome like '%"&busca&"%' " : End If

  '*** Verifico se a coluna 'TamId' da tabela 'tbl_produtos está preenchida - se estiver acrescento este trecho na string
  If not RsTam.Eof then : SqlSearch = SqlSearch & "or tbl_tamanhos.TamNome like '%"&busca&"%' " : End If

  '*** Verifico se a coluna 'CorId' da tabela 'tbl_produtos está preenchida - se estiver acrescento este trecho na string
'   If not RsCor.Eof then : SqlSearch = SqlSearch & "or tbl_cores.CorNome like '%"&busca&"%' " : End If

  '*** Verifico se a coluna 'FabId' da tabela 'tbl_produtos está preenchida - se estiver acrescento este trecho na string
'   If not RsFab.Eof then : SqlSearch = SqlSearch & "or tbl_fabricantes.FabNome like '%"&busca&"%' " : End If

  '*** Verifico se a coluna 'UnidId' da tabela 'tbl_produtos está preenchida - se estiver acrescento este trecho na string
'   If not RsUnid.Eof then : SqlSearch = SqlSearch & "or tbl_unidades.UnidNome like '%"&busca&"%' " : End If

  '*** Encerro a seleção
  Set RsSearch = Conn.execute(SqlSearch)


  '*** Crio o loop de apresentação dos resultados obtidos
  While not RsSearch.eof

     Response.write (RsSearch("ProdId")&" - "&RsSearch("ProdNome")&" - "&Left(RsSearch("ProdDescricao"), 30)&"<br />")

  RsSearch.movenext
  Wend

 

Qual é a forma correta de se fazer isto, com menos selects e obtendo um resultado perfeito e limpo?

 

Obrigado!

 

Alex_ps

Compartilhar este post


Link para o post
Compartilhar em outros sites

Seria assim, select com varios inner join

select * from table1 as a inner join table2 as b on a.id=b.Idtable2 inner join table3 as c on b.id=c.idTable3

voce tem pode usar as clausulas WHERE e AND etc.

select * from table1 as a inner join table2 as b on a.id=b.Idtable2 inner join table3 as c on b.id=c.idTable3
where a.id=1 and b.id=2

Isso vai depender do que voce esta querendo recuperar.

 

Valeu

Compartilhar este post


Link para o post
Compartilhar em outros sites

Oi Gilberto,

 

Obrigado por sua ajuda!

Entretanto, me parece que estamos falando a mesma coisa, com a única diferença que você está substituindo por "as a", "as b" um "comando" enquanto eu estou "descrevendo" o comando.

Por favor, veja, o problema não aparece na estrutura que eu estou utilizando, ele surge quando por exemplo eu acrescento ao inner join uma coluna que não foi preenchida em nenhuma linha.

Existem clientes que não cadastram tamanhos, outros não cadastram modelos, etc, e eu não queria ter que refazer o código, cada vez que instalo o sistema.

Deve ter um jeito de fazê-lo conforme apresentei no meu código, que eu possa utilizá-lo, sem que apresente risco ao resultado.

Outra coisa que chamou a atenção foi a filtragem quando no caso de conjunção entre duas colunas.

Ou seja, o que era para ser apresentado como 4, aparece 2, etc.

Por favor, veja se agora fica claro.

Obrigado.

 

Alex

Compartilhar este post


Link para o post
Compartilhar em outros sites

você precisa ter uma relacionamento entre as tabelas, na verdade, a importância de uma modelagem de dados bem definida até os mínimos detalhes, como os campos de relacionamentos, um velho ditado diz, que um relacionamento bem definido é a alma do aplicativo, pois daí saem todas as consultas e operações com o banco, influenciando diretamente na otimização e performance do aplicativo

Compartilhar este post


Link para o post
Compartilhar em outros sites

wbatera,

 

Obrigado por sua ajuda!

Eu já havia visto este tal "left join" quando estudei o "inner join", mas eu não sabia para quê e quando utilizá-lo.

Graças a sua gentil ajuda, eu descobri.

O problema era exatamente este mesmo.

O "inner join" vai perdendo as informações na medida em que as conjunções vão sendo realizadas, com base em tabelas com campos vazios.

O "left join" dá continuidade no processo sem ter nenhuma perda.

 

Um bom dia a todos.

 

Alex_ps

Compartilhar este post


Link para o post
Compartilhar em outros sites

A diferença do Inner Join para o Left Join é que o Inner Join ele tras conteudos que existem nas duas tabelas, e o left join tras todas as informacoes qeu existe na tabela da esquerda, ou seja a primeira que voce usou no select e consequentemente os dados que existem na tabela da direita que esta amarrada a da esquerda atraves de um id etc.

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.