Запрос MySQL с 3 и более вариантами OR

86
13 июня 2021, 02:30

Помогите, делаю поиск по БД, но не могу понять как правильно сформировать запрос. Есть таблица, в которой 10 столбцов, Я хочу что бы через форму поиска, можно было найти строки, по заданным параметрам столбцов, для этого использую конструкцию 'OR', но если первое значение unknow, а в 3 добавить данные - то поиск возвращается пустой:

SELECT * FROM default_fpl WHERE `departure` LIKE '' 
                            OR `arrival` LIKE ''
                            OR `route`  LIKE 'MARSHUT'
                            OR `commentaries` LIKE '' 
                            OR `FPL_name` LIKE '' LIMIT 50

Данный запрос вернет 0 резльтатов, но стоит изменить чуть-чуть:

SELECT * FROM default_fpl WHERE `departure` LIKE 'UUUU' 
                            OR `arrival` LIKE ''
                            OR `route`  LIKE 'MARSHUT'
                            OR `commentaries` LIKE '' 
                            OR `FPL_name` LIKE '' LIMIT 50

Тогда возвращается только значение по первому совпадению, т.е. UUUU

Как правильно сформировать запрос, что бы поиск происходил по разным столбцам?

В PDO запрос выглядит так:

         $fplfindSql = "SELECT * FROM default_fpl WHERE departure LIKE :departure 
                        OR arrival LIKE :arrival
                        OR route LIKE :route 
                        OR commentaries LIKE :comment 
                        OR FPL_name LIKE :fplname LIMIT 50";
         $params = [':departure' => $departure,
                    ':arrival'=>$arrival,
                    ':route'=>$route,
                    ':comment'=>$comment,
                    ':fplname'=>$fplname];
         $stmt = $pdo->prepare($fplfindSql);
         $stmt->execute($params);

Или сделать отдельный запрос для каждой переменной? Но тогда нагрузка на базу будет расти?

Answer 1

Генерируйте запрос динамически

    $sql = "SELECT * FROM default_fpl ";
    $where = '';
    foreach ($data as $key => $val){
        if (!empty($val)){
           if (!empty($where))
              $where .= ' AND ';
           $where .= " `{$key}` LIKE '%{$val}%' ";
        }
    }
    if (!empty($where))
      $sql .= ' WHERE '. $where;
    $sql .= ' LIMIT 50';

Чтото на подобии такого.. условия легко можна регулировать для пдо цикл можно изменить на пример ниже, но не уверен как тут генерит like.

      foreach ($params as $key => $val){
        if (!empty($val)){
           if (!empty($where))
              $where .= ' AND ';
              $fieldName = ltrim($key, ':');
           $where .= "`{$fieldName}` LIKE {$key}";
        }
Answer 2

Убери Like и замени на равно:

Если нужно чтобы все условия выполнились:

SELECT * FROM `moder` WHERE `pred` = '0' AND `kik` = '0' AND `tban` = '0' AND `ban` = '0' AND `mut` = '0'

Если нужно чтобы только одно из них:

SELECT * FROM `moder` WHERE `pred` = '0' OR `kik` = '0' OR `tban` = '0' OR `ban` = '0' OR `mut` = '0'

Answer 3

Измените шаблон основы запроса, сделайте его таким:

SELECT * FROM default_fpl WHERE 1=1

И затем добавляйте условия только для тех полей, которые заданы, в форме

OR `route` LIKE 'MARSHUT'

Когда закончите, навесьте на хвост требуемое

LIMIT 50

В итоге получите запрос без проверок на пустые поля.

LIKE с шаблоном, который не содержит подстановочных знаков, представляет из себя фактически проверку на равенство - только с дополнительными, нафиг не нужными, операциями.

Если Вы проверяете полное значение поля - вместо показанного выше добавляемого условия должно быть

OR `route` = 'MARSHUT'
READ ALSO
Запаковать видео в бинарный файл

Запаковать видео в бинарный файл

Пытаюсь загрузить видео на Facebook через Graph-Api, там указано:

112
Очистка таблиц MySQL

Очистка таблиц MySQL

Имеется БД сайта на Битриксе на хостинге, сильно раздулась одна из таблиц, более 1 000 000 записейНеобходимо удалить все записи, кроме созданных...

83