To do a complex search I would have to use OR to combine all the instructions?

Asked

Viewed 248 times

0

I would like a help to make SQL as per the data in this figure.

What I know is that if I send AND for all characteristics and one of them return false or erro all SQL will be compromised.

I thought I’d do it with OR. Is it right? But if I do, one of the characteristics can be ignored, no?

Follow the code I have so far

# Essa variável pega os tipos enviados por $_GET e separá-os.
$tipos  = (@explode('/', implode('/', $_GET['tipo'])));

# Esse foreach pega cada variável e monta a instrução
# **CATEGORIA LIKE '%{$word}% OR**
foreach($tipos as $word){
    $sql[] = "CATEGORIA LIKE '%{$word}%'";
}

# Então SQL pega o resultado do foreach e colocar no WHERE
# e eu termino de ordenar os resultados.
$sql    = 'SELECT * FROM imovel WHERE ' .implode(' OR ', $sql);
$sql   .= ' ORDER BY IMO_CODIGO DESC LIMIT '.$inicio. ', '. $limite;

inserir a descrição da imagem aqui

  • 1

    For the same category ex: type, dormintorios etc, you can use the IN and then the AND SELECT * FROM tabela where dormintorio IN(1,2,3) AND tipo in('Casa', 'Cobertura')

  • @lost if my guy return vazio, Wouldn’t that give SQL error? This is my question !!!

2 answers

4

Assembling a filter


ATTENTION: Always validate your variables before sending them to the database.

Validating the filter

If values are standard, use a code instead of a word in search, so you’ll always have consistent results.

$where = 'WHERE 1=1 AND ';

$tipo = Array(
  1, // Apartamento
  2, // Casa
  3  // Terreno
);

if (isset($tipo) && !empty($tipo)){

    // se $tipo for um array e for maior que 0
    if (is_array($tipo) && count($tipo) > 0) {
       $where .= " tipo IN ('".implode("','",$tipo)."') AND ";
    } else {
       $where .= " tipo = '{$tipo}' AND ";
    }

}

$dormitorio = Array(2,3,4); // Quantidade de dormitorios

if (isset($dormitorio) && !empty($dormitorio)){

   if (is_array($dormitorio) && count($dormitorio) > 0){
     $where .= " dormitorio IN ('".implode("', '", $dormitorio)."') AND ";

   } else {
     $where .= " dormitorio = '{$dormitorio}' AND ";
   }
}

I recommend sending the filter via POST, but can also be done via GET, no problem. Always remember to avoid SQL Injection, here a question on the subject.

Validate the received data to check which fields will enter the query as done in the above example (if (isset($tipo) && !empty($tipo)){, if (isset($dormitorio) && !empty($dormitorio)){, if (isset($dormitorio) && !empty($dormitorio)){), it is good to do this with the variables received from the form ($_POST, $_GET).




Searching for a Keyword

And if the user can do a keyword search.

$palavrachave = 'Sacada';

if (isset($palavrachave) && !empty($palavrachave)){
  // Adicione todos os campos que possa ser buscado como palavra chave
  $where .= "(nome LIKE '%{$palavrachave}%' OR descricao LIKE '%{$palavrachave}%' OR cidade LIKE '%{$palavrachave}%') AND "; 
}

Add all fields that contain text content to the keyword query if you use this in your filter. Mount a block between parentheses using OR, so that all results that have the term in any of the fields, is brought in the result, and concatenates with the rest of the filter with AND.




Table-riding

$sql = "SELECT * FROM imoveis ".trim($where,' AND ');

Put a AND after each query field and when adding the fields in the query remove only the last one using a trim. And even if there is no filter, there will be no problems as we start the WHERE searching for all results where 1=1 be true, ie all. And the AND of that expression will be removed ($where = 'WHERE 1=1 AND ';), resulting in WHERE 1=1.




Upshot

All information provided:

SELECT * FROM imoveis WHERE 1=1 AND  tipo IN ('1','2','3') AND  dormitorio IN ('2', '3', '4') AND (nome LIKE '%Sacada%' OR descricao LIKE '%Sacada%' OR cidade LIKE '%Sacada%')

The search will bring all the data that the field type has the value 1, 2 or 3, informed in the variable $tipo, 2, 3 or 4 in the field dormitorio, informed in the variable $dormitorio, and having the password Sacada name, description or city, entered in the variable $palavrachave.

Without the field tipo informed:

SELECT * FROM imoveis WHERE 1=1 AND  dormitorio IN ('2', '3', '4') AND (nome LIKE '%Sacada%' OR descricao LIKE '%Sacada%' OR cidade LIKE '%Sacada%')

The query will return all data that has the value 2, 3 or 4 in the field dormitorio, informed in the variable $dormitorio, and hold the keyword in the name, description or city.

No field informed:

SELECT * FROM imoveis WHERE 1=1

The query will return all table data.

  • And case guy return empty, it will be discarded in SQL?

  • 1

    Yes, then it will bring all the results regardless of the type, because it will not be added in the WHERE query. You have to validate the variable, so that it is included or not in the query filter.

  • How would it look $guy whereas I’m getting it by $_GET? I’m getting tipo=Apartamento&tipo=Casa&tipo=Terreno.

  • 1

    So, as I said there in the reply use na busca um código em vez de uma palavra, but if there is no way you can do it now (but try to do it later). Try to send the data like this tipo=Apartamento+Casa+Terreno, and then blow up $tipo = explode('+',$_GET['tipo']). And then just follow the proposed model.

  • If you wear it like that tipo=Apartamento&tipo=Casa&tipo=Terreno, the latter will always be superimposed on the previous(s), you can also do so tipo[]=Apartamento&tipo[]=Casa&tipo[]=Terreno, that then you will receive the data correctly.

  • see if you can help me here >>> http://answall.com/questions/35079/rewrite-o-c%C3%B3digo-to-show-expected result ... your code is working perfectly but I have a problem.

  • Already I helped there, if that answer was helpful, give a plus and mark as accepted.

Show 2 more comments

1

You must use and and or separated into blocks with parentheses, for example:

(tipo = apartamento or tipo = casa) and 
(dormitórios = 2 or dormitórios = 3) and 
(vagas = 1 or vagas = 2) and 
(area > 60 and area < 120) and 
(valor > 100000 and valor < 150000)

Sorry the quality of the answer, I’m on mobile, as soon as possible edit and improve...

  • Now I’m going to tell you what might be the subject of this question: and if you like return vazio, this will return an error in SQL no?

  • 3

    @Marcosvinicius You will have to not include in the query the filters not filled by the user.

  • @Caffé could show me this in SQL form in an answer?

  • 3

    @Marcosvinicius In this case, you don’t have SQL. The idea is: you have to have the ability to know whether or not a filter has been filled by the user. Filled filters enter your SQL command as described by Jader, and unfilled filters you simply ignore. That is: you will have to build your SQL dynamically based on what was or was not filled by the user; you cannot leave the query ready just by passing the parameters at the time of running. I was able to explain?

  • Understood this @Caffé the business will be the ability to assemble SQL according to the fields sent. Thank you for what you have done so far.

  • 2

    @Marcosvinicius Se tipo is not filled in by the user ("empty return"), do not include a filter for type in your query. Jader’s query would look like this: (dormitórios = 2 or dormitórios = 3) and (vagas = 1 or vagas = 2) and (área > 60 and área < 120) and (valor > 100000 and valor < 150000). Whereas your business rule is: "if user does not select a type, bring real estate of any kind", the type simply goes away from the query.

  • @Marcosvinicius That’s right. For nothing. And good luck!

  • @Caffé you can show me a way to print the sql that is being sent so that I can view the SQL that is being sent beyond WARNINGS, FATAL etc ...

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.