Как сделать SQL-запрос, исключающий строки без всех параметров - PullRequest
1 голос
/ 18 апреля 2019

У меня есть окно поиска, которое я даю пользователю для ввода ключевых слов, которые он хочет найти. При отправке я разделяю слова в поле ввода (если их несколько) на массив и выполняю запрос для каждого отдельного слова. С помощью SQL я могу получить результаты, которые имеют хотя бы одно из значений, проблема в том, что я хочу получать только те строки, которые содержат как минимум все параметры в одном столбце или другом.

public function employeeSearchAction()
    {
        if ($this->user_permissions < 1) {
            return 0;
        }
        // split search string into array based on spaces
        if ($this->data != '') {
            $searchParams = explode(' ', trim($this->data));
            // get any rows with any one of these values in them
            foreach ($searchParams as $s) {
                $this->db->orWhere('user_firstname', '%'.$s.'%', 'like');
                $this->db->orWhere('user_lastname', '%'.$s.'%', 'like');
                $this->db->orWhere('user_email1', '%'.$s.'%', 'like');
                $this->db->orWhere('user_phn_1', '%'.$s.'%', 'like');
                $this->db->orWhere('user_phn_2', '%'.$s.'%', 'like');
                $this->db->orWhere('user_phn_3', '%'.$s.'%', 'like');
                // $this->db->orWhere('user_address1', '%'.$s.'%', 'like');
                $this->db->orWhere('user_position', '%'.$s.'%', 'like');
                $this->db->orWhere('user_type', '%'.$s.'%', 'like');
                $this->db->orWhere('user_division', '%'.$s.'%', 'like');
                // $this->db->orWhere('user_position', $s);
                // $this->db->orWhere('user_type', $s);
                // $this->db->orWhere('user_division', $s);
            }
            $this->db->having('owner_id', $this->owner_id);
            $binaryArray = array_fill(0, sizeof($searchParams), 0);
            $results = $this->db->get('tblusers');
            $filtered = [];
            // filter rows to ensure that all rows have every parameter
            foreach ($results as $r) {
                $binaryArray = array_fill(0, sizeof($searchParams), 0);
                foreach ($binaryArray as $key=>$b) {
                    if (strpos(strtolower($r['user_firstname']), strtolower($searchParams[$key])) !== false ||
                  strpos(strtolower($r['user_lastname']), strtolower($searchParams[$key])) !== false ||
                  strpos($r['user_email1'], strtolower($searchParams[$key])) !== false ||
                  strpos($r['user_phn_1'], strtolower($searchParams[$key])) !== false ||
                  strpos($r['user_phn_2'], strtolower($searchParams[$key])) !== false ||
                  strpos($r['user_phn_3'], strtolower($searchParams[$key])) !== false ||
                  strpos(strtolower($r['user_position']), strtolower($searchParams[$key])) !== false ||
                  strpos(strtolower($r['user_type']), strtolower($searchParams[$key])) !== false ||
                  strpos(strtolower($r['user_division']), strtolower($searchParams[$key])) !== false
                  // strpos($r['user_address1'], strtolower($searchParams[$key])) !== false
                ) {
                        $binaryArray[$key] = 1;
                    }
                }
                if (!in_array(0, $binaryArray)) {
                    $filtered[] = $r;
                }
            }
        } else {
            $this->db->where('owner_id', $this->owner_id);
            $filtered = $this->db->get('tblusers');
        }
        foreach ($filtered as $r) {
            $user_phn_1 = $r['user_phn_1'] == '' ? 'N/A' : '<a href="tel:+1'.$r['user_phn_1'].'">'.preg_replace("/[^0-9]/", "", $r['user_phn_1']).'</a>';
            $user_phn_2 = $r['user_phn_2'] == '' ? 'N/A' : '<a href="tel:+1'.$r['user_phn_2'].'">'.$r['user_phn_2'].'</a>';
            $user_position = $r['user_position'] == '' ? 'N/A' : $r['user_position'];
            $user_type = $r['user_type'] == '' ? 'N/A' : $r['user_type'];
            $user_division = $r['user_division'] == '' ? 'N/A' : $r['user_division'];
            $user_email1 = $r['user_email1'] == '' ? 'N/A' : '<a href="mailto:'.$r['user_email1'].'">'.$r['user_email1'].'</a>';
            $user_address1 = $r['user_address1'] == '' ? 'N/A' : '<a href="https://maps.google.com/maps?q='.$r['user_address1'].'">'.$r['user_address1'].'</a>';
            $user_firstname = $r['user_firstname'] == '' ? 'N/A' : $r['user_firstname'];
            $user_lastname = $r['user_lastname'] == '' ? 'N/A' : $r['user_lastname'];
            $r['is_ready'] != 1 ? $user_firstname .=  ' <i title="Employee is not ready to work." class="orange fas fa-exclamation-triangle"></i>' : '';
            echo "
            <div class='search-form_row-container'>
              <div class='col-xs-6 col-sm-6'>
                 <i class='fas fa-file-signature'>
                 <span class='results-text results-text--name'>$user_lastname $user_firstname</span>
                 </i>
              </div>
              <div class='col-xs-6 col-sm-6'>
               <i class='fas fa-phone'>
                <span class='results-text results-text--phone'>{$user_phn_1}</span>
               </i>
              </div>
              <div class='col-xs-6 col-sm-6'>
                <a href='/includes/sql/store/users/curr_user.php?id={$r['user_id']}&goto=/users/user_profile_main.php'>
                 <i class='fas fa-link'>
                 <span class='results-text results-text--edit'>View Profile</span>
                 </i>
                </a>
              </div>
              <div class='col-xs-6 col-sm-6'>
                 <i class='fas fa-suitcase-rolling'>
                 <span class='results-text results-text--position'>$user_position</span>
                 </i>
              </div>
              <div class='col-xs-6 col-sm-6'>
                 <i class='fas fa-map-marker-alt'>
                 <span class='results-text results-text--type'>$user_type</span>
                 </i>
              </div>
              <div class='col-xs-6 col-sm-6'>
                 <i class='fas fa-i-cursor'></i>
                 <span class='results-text results-text--division'>$user_division</span>
                 </i>
              </div>
          </div>
        ";
        }
    }

Какие у меня функции, как и должно быть, но я не могу не заметить, насколько это невероятно некрасиво и неэффективно. Глядя на код, который вы знаете, я не использую необработанные запросы, я использую https://github.com/ThingEngineer/PHP-MySQLi-Database-Class Mysqlidb. Если вы хотите отказаться от формулировки своего ответа в этом формате, хорошо, эта библиотека может использовать необработанные запросы. Любая помощь приветствуется. Я бы предпочел получить только те записи, которые содержат все параметры, а не записи, содержащие хотя бы один, и затем отфильтровать их с помощью PHP.

Редактировать: мое намерение состоит в том, чтобы иметь возможность просто сделать с этим SQL

1 Ответ

0 голосов
/ 28 июня 2019

Вам нужно запустить запрос, который выбирает данные для всех пользователей. Для каждого пользователя необходимо проверить, содержат ли данные этого пользователя каждое ключевое слово. Если данные пользователя содержат все ключевые слова, то пользователь может быть включен в результаты поиска.

Так что вам нужно иметь вложенные циклы. Внешний цикл проверяет каждого пользователя. Внутренний цикл проверяет каждое ключевое слово в данных пользователя. Если данные пользователей содержат все ключевые слова, то включите пользователя в результаты поиска. Если одно из ключевых слов отсутствует в данных пользователя, прервите внутренний цикл и проверьте следующего пользователя.

...