Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
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:
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"' Dim SqlUnid, RsUnid
' SqlUnid = "Select UnidId from tbl_produtos where UnidId <> ''"
' SqlUnid = "Select UnidId from tbl_produtos where UnidId is not null"'*** 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'*** 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
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
já tentou utilizar o LEFT JOIN ?
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
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
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.
voce tem pode usar as clausulas WHERE e AND etc.
Isso vai depender do que voce esta querendo recuperar.
Valeu