none
Query complicada RRS feed

  • Pergunta

  • Pessoal,

    Estou para montar uma consulta e não sei como devo proceder.

    É uma busca de imóveis, o usuário tem a opção de selecionar mais de um tipo de imóvel, mais de uma situação do imóvel, mais de uma opção de quartos, faixa de valor, bairro.

    Se eu montar uma string com OR e AND no WHERE será que funciona?

    Estou desenvolvendo a aplicação com ASP.NET 3.5 acessando Sql Server 2005.

    Agradeço desde já.

    Att.
    Cristiano
    sexta-feira, 21 de novembro de 2008 12:56

Respostas

  • Boa Noite,

     

    O importante é que a consulta tenha um comportamento parecido com o abaixo:

     

    Se nenhum parâmetro foi informado
    Select * from imoveis

     

    Se o tipo imóvel foi informado e o situação do imóvel não foi informada
    Select * from imoveis WHERE tipoimovel IN (Valor1,Valor2)

     

    Se o tipo imóvel foi informado e o situação do imóvel foi informada
    Select * from imoveis WHERE tipoimovel IN (Valor1,Valor2) AND Situacao = Valor

     

    Se o tipo imóvel não foi informado e o situação do imóvel foi informada
    Select * from imoveis WHERE Situacao = Valor

     

    Quando algo não é informado, não precisamos colocar todos os valores possíveis, mas sim fazer com que não apareça na cláusula WHERE.

     

    [ ]s,

     

    Gustavo

    domingo, 23 de novembro de 2008 22:14

Todas as Respostas

  • Bom Dia Cristiano,

     

    Você poderia exemplificar colocando a consulta e o resultado esperado ? Acho que assim ficaria mais fácil.

     

    [ ]s,

     

    Gustavo

     

    sexta-feira, 21 de novembro de 2008 13:18
  • Cristiano,

     

    Mas o que exatamente esta consulta deverá buscar e retornar de informações?

    sexta-feira, 21 de novembro de 2008 13:43
  • Esta é a tela da busca:

    http://www.imoveiscaxiasdosul.com.br/busca-imoveis.aspx

    Notem que o usuário pode escolher múltiplas opções, vamos imaginar que faça a seguinte seleção nessa tela:
    Tipo de Imóvel: apartamento(id = 1), casa(id =2), sobrado(id = 3)
    Situação do Imóvel: novo(id=1) ou usado(id =2)
    Dormitórios: 2 ou 3


    Então vamos supor que a string seja a seguinte:

    Select * from imoveis WHERE tipo_imovel = 1 OR tipo_imovel = 2 OR tipo_imovel = 3 AND situacao = 1 OR situacao = 2 AND dormitorios = 2 OR  dormitorios = 3

    Essa seria a melhor maneira?
    Assim funcionaria legal?

    Deve-se levar em conta que poderia ser selecionado mais opções do que este exemplo.

    Fico no aguardo de um retorno.

    Obrigado a todos que estão me ajudando.

    Abraço

    Cristiano

    sábado, 22 de novembro de 2008 14:47
  • Boa Tarde,

     

    Certamente essa não é a melhor forma de fazê-lo. Primeiro porque essa consulta não irá trazer o resultado esperado. Imagine por exemplo a seguinte necessidade: Recuperar todos os imóveis do tipo apartamento. A situação do imóvel ou a quantidade de dormitórios não é relevante. Pela proposta teríamos:

     

    Code Snippet

    Select * from imoveis WHERE tipo_imovel = 1 AND

    situacao = 1 OR situacao = 2 AND dormitorios = 2 OR dormitorios = 3

     

    Em todo caso, com essa quantidade de ORs e sem a utilização do parênteses, a consulta irá retornar os apartamentos (tipo_imovel = 1) ou qualquer outro imóvel cuja situação seja 1 ou 2 ou qualquer outro imóvel cuja quantidade de dormitórios seja 2 ou 3. Em outras palavras todos os imóveis serão recuperados. E isso acontecerá para qualquer critério de pesquisa. A única consulta que funcionará será a que especificar o tipo_imovel, a situação e a quantidade de dormitórios, mas provavelmente essa não será a consulta mais freqüente.

     

    Outro ponto negativo é que você precisa especificar todos os tipos de imóvel, todos as situações e quantidade de dormitórios. Se surgir um novo tipo de imóvel, uma nova situação ou uma outra quantidade de dormitórios você terá que alterar todas as suas consultas. Acho que melhor forma de fazer é avaliar se uma determinada condição é ou não verdadeira. Ex:

     

    Instrução SELECT fixa
    strSQL = "SELECT * FROM Imoveis WHERE 1 = 1 "

     

    -- Se o tipo_imovel for preenchido
    Adicione um AND especificando o tipo_imovel

     

    -- Se a situação for preenchida
    Adicione um AND especificando a situação

     

    -- Se a quantidade de dormitórios for preenchida
    Adicione um AND especificando a quantidade de dormitórios

     

    Dessa forma a consulta só irá contemplar o especificado. Se você informar a situação haverá uma cláusula WHERE informando a situação somente. Se você informar a situação e quantidade de dormitórios haverá uma cláusula WHERE especificando apenas a situação e a quantidade de dormitórios.

     

    [ ]s,

     

    Gustavo

    sábado, 22 de novembro de 2008 15:55
  • Olá, Uma outra forma, sem ser montando o Sql Dinamicamente, seria deixar o sql já pronto numa stored procedure

     

    Exemplo para a consulta que Gustavo postou:

     

    Code Snippet

    select * from imoveis

    where

    ( @tipo_imovel = '0' or @tipo_imovel = tipo_imovel )

    and ( @qtdDormitorios= '0' or @qtdDormitorios = tipo_imovel )

     

     

     

     

    Ou seja, quando você quiser filtrar por determinados valores basta passar o parâmetro, quando não, é só passar '0' (ou outro valor padrão escolhido por você) como parâmetro para que a cláusula seja anulada.

     

    Abraços

    domingo, 23 de novembro de 2008 13:19
  • Bom dia Gustavo,

    Obrigado por sua ajuda, mas vamos lá.

    Para os checkbox eu uso o checkboxlist e estava pensando em fazer um for para montar a query.
    Então se surgir opções novas no tipo de imóvel e etc não haverá problemas.

    Também faria a verificação se foi selecionado algum check ou se os DropDown foram selecionados, então, só se eles foram selecionados eu coloco o "AND ...." na query.

    Outra coisa, no seu exemplo só é selecionado 1 Tipo_Imovel, na verdade podem ser selecionados vários. Essa parte eu não entendi direito na sua explicação. Se pude me ajudar.

    ---------------------------------------------------------------------------

    Demétrio,

    Seria legal essa montagem através de storeprocedure, mas fico com a mesma dúvida, a pessoa pode selecionar 1 tipo_imóvel como pode selecionar 2, 3, 4. Como montar isso?

    ---------------------------------------------------------------------------

    Um amigo me comentou sobre o EXISTS, que seria uma boa maneira de fazer isso, mas eu nunca usei e achei um pouco complicado. Mas se for o caso quebro a cabeça e uso.


    O que vocês acham pessoal?

    Abraço,

    Cristiano
    domingo, 23 de novembro de 2008 15:04
  • Boa Noite,

     

    O importante é que a consulta tenha um comportamento parecido com o abaixo:

     

    Se nenhum parâmetro foi informado
    Select * from imoveis

     

    Se o tipo imóvel foi informado e o situação do imóvel não foi informada
    Select * from imoveis WHERE tipoimovel IN (Valor1,Valor2)

     

    Se o tipo imóvel foi informado e o situação do imóvel foi informada
    Select * from imoveis WHERE tipoimovel IN (Valor1,Valor2) AND Situacao = Valor

     

    Se o tipo imóvel não foi informado e o situação do imóvel foi informada
    Select * from imoveis WHERE Situacao = Valor

     

    Quando algo não é informado, não precisamos colocar todos os valores possíveis, mas sim fazer com que não apareça na cláusula WHERE.

     

    [ ]s,

     

    Gustavo

    domingo, 23 de novembro de 2008 22:14