Как реализовать поиск по нескольким вхождениям в MySQL?

Здравствуйте! Как оптимально организовать поиск по нескольким ключевым словам в комбинации PHP (PDO) и MySQL? В данный момент я использую следующий запрос: <br/> <pre><code class="sql">SELECT * FROM articles WHERE name LIKE "%опух%" AND LIKE "%поч%"</code></pre> для нахождения статей, таких как "Диагностика опухолей почек" и "Лечение почечных злокачественных опухолей". Однако у меня возникают сложности с формированием подготовленных выражений в PHP (PDO). Существует ли более эффективное решение? Спасибо!
  • 15 января 2025 г. 16:43
Ответы на вопрос 2
Здравствуйте!

Ваш текущий SQL-запрос имеет небольшую ошибку в синтаксисе. Правильный запрос будет выглядеть так:

```sql
SELECT * FROM articles WHERE name LIKE "%опух%" AND name LIKE "%поч%";
```

Если вы хотите выполнять поиск по нескольким ключевым словам, одним из наиболее оптимальных и безопасных способов будет использование подготовленных выражений (prepared statements) в сочетании с PDO в PHP. Это поможет избежать SQL-инъекций и повысить производительность, особенно при работе с большим объемом данных.

Вот пример, как можно организовать поиск по нескольким ключевым словам:

1. **Соберите ключевые слова в массив**.
2. **Сформируйте SQL-запрос с использованием подготовленных выражений**.

Пример кода на PHP:

```php
// Подключение к базе данных с использованием PDO
try {
    $pdo = new PDO('mysql:host=your_host;dbname=your_db', 'your_user', 'your_password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Ключевые слова для поиска
    $keywords = ['опух', 'поч'];

    // Генерация частей запроса
    $whereClauses = [];
    foreach ($keywords as $keyword) {
        $whereClauses[] = "name LIKE ?";
    }

    // Объединение частей запроса с использованием 'AND'
    $sql = 'SELECT * FROM articles WHERE ' . implode(' AND ', $whereClauses);
    
    // Подготовка запроса
    $stmt = $pdo->prepare($sql);
    
    // Привязка параметров
    foreach ($keywords as $i => $keyword) {
        $stmt->bindValue($i + 1, '%' . $keyword . '%', PDO::PARAM_STR);
    }

    // Выполнение запроса
    $stmt->execute();

    // Получение результатов
    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);

    // Обработка результатов
    foreach ($results as $article) {
        echo $article['name'] . '<br />';
    }

} catch (PDOException $e) {
    echo 'Ошибка подключения: ' . $e->getMessage();
}
```

### Объяснение кода:

- **Подключение к базе данных**: Используется PDO для безопасного соединения.
- **Сбор ключевых слов**: Вы можете изменять массив `$keywords` в зависимости от ваших нужд.
- **Создание запроса**: Для каждого ключевого слова создается условие `LIKE`, и они объединяются с помощью `AND`.
- **Подготовка и выполнение запроса**: Запрос подготавливается, параметры привязываются, и затем он выполняется.
- **Вывод результатов**: Результаты выводятся на экран.

Этот подход позволит вам гибко добавлять количество ключевых слов и эффективно выполнять поиск по ним.
Но тут возникает проблема в формировании prepared statements в PHP (PDO).
А в чем проблема?
$sql = 'SELECT * 
FROM articles 
WHERE name LIKE ? 
AND LIKE ?';
$prep = $dbh->prepare($sql);
$ret = $prep->execute(['%' . 'опух' . '%', '%' . 'поч' . '%']);
Похожие вопросы