10

SQL SELECT WHERE поле содержит слова

18

Я столкнулся с проблемой формирования SQL-запроса, который возвращал бы результаты в определенном формате. Мне нужно выполнить запрос, который возвращал бы строки из таблицы, соответствующие следующим критериям:

SELECT * FROM MyTable WHERE Column1 CONTAINS 'word1 word2 word3'

При этом важно, чтобы в результаты входили все строки, содержащие все три слова, независимо от их порядка. То есть результаты должны включать такие комбинации, как 'word2 word3 word1', 'word1 word3 word2' или любые другие перестановки этих трех слов.

Мне нужно, чтобы в результирующих строках присутствовали все указанные слова. Как можно реализовать этот запрос?

5 ответ(ов)

15

Если вам нужно включить любое из слов, вы можете использовать следующий запрос:

SELECT * FROM mytable
WHERE column1 LIKE '%word1%'
   OR column1 LIKE '%word2%'
   OR column1 LIKE '%word3%'

Если же требуется, чтобы все слова были присутствующи, используйте:

SELECT * FROM mytable
WHERE column1 LIKE '%word1%'
  AND column1 LIKE '%word2%'
  AND column1 LIKE '%word3%'

Однако данный метод может быть довольно медленным. Для достижения более быстрой работы стоит рассмотреть использование полнотекстового поиска, который зависит от типа вашей базы данных и имеет свои особенности.

1

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

Если ваш диалект SQL поддерживает CHARINDEX, то использовать его гораздо проще:

SELECT * FROM MyTable
WHERE CHARINDEX('word1', Column1) > 0
  AND CHARINDEX('word2', Column1) > 0
  AND CHARINDEX('word3', Column1) > 0

Кроме того, имейте в виду, что этот метод и метод из принятого ответа охватывают только сопоставление подстрок, а не сопоставление слов. Таким образом, например, строка 'word1word2word3' всё равно будет соответствовать условиям поиска.

0

Для работы с MySQL можно использовать функцию, аналогичную приведенной ниже, для разделения строки и поиска уникальных слов в таблице. Однако непосредственно такой синтаксис, как в T-SQL, в MySQL не поддерживается. Вот как это можно реализовать в стиле запроса к MySQL:

Вспомогательная Функция

Для начала, давайте создадим функцию, которая будет делить строку на части:

DELIMITER //

CREATE FUNCTION fnSplit(input VARCHAR(512), sep VARCHAR(1))
RETURNS TEXT
BEGIN
    DECLARE output TEXT DEFAULT '';
    WHILE INSTR(input, sep) > 0 DO
        SET output = CONCAT(output, SUBSTRING_INDEX(input, sep, 1), '|');
        SET input = SUBSTRING(input, INSTR(input, sep) + LENGTH(sep));
    END WHILE;
    SET output = CONCAT(output, input); -- добавляем последний элемент
    RETURN output;
END //

DELIMITER ;

Пример Запроса

Теперь можно использовать эту функцию для поиска слов word1, word2, word3 в столбце Column1 таблицы MyTable. Поскольку в MySQL нет встроенной функции для работы с множеством строк, мы можем обойтись следующим образом:

-- Создаем временную таблицу для сохранения уникальных слов
CREATE TEMPORARY TABLE FilterTable (Data VARCHAR(512));

-- Заполняем таблицу уникальными словами для поиска
INSERT INTO FilterTable (Data)
SELECT DISTINCT SUBSTRING_INDEX(S.word, '|', 1) AS Data
FROM (
    SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(fnSplit('word1 word2 word3', ' '), '|', n.n), '|', -1) as word
    FROM (
        SELECT 1 n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 
        UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 
        UNION ALL SELECT 9 UNION ALL SELECT 10
    ) n
    WHERE n.n <= (LENGTH('word1 word2 word3') - LENGTH(REPLACE('word1 word2 word3', ' ', '')) + 1)
) AS S;

-- Ищем в "MyTable" по "Column1"
SELECT DISTINCT T.*
FROM MyTable T
INNER JOIN FilterTable F1 ON T.Column1 LIKE CONCAT('%', F1.Data, '%')
LEFT JOIN FilterTable F2 ON T.Column1 NOT LIKE CONCAT('%', F2.Data, '%')
WHERE F2.Data IS NULL;

Пояснения

  1. fnSplit: Эта функция делит строку на составляющие, используя заданный разделитель (sep) и возвращает все части, соединенные символом-проводником (в данном примере — '|').

  2. Временная таблица FilterTable: Здесь мы сохраняем уникальные слова для поиска.

  3. Запрос: Мы сначала выполняем поиск, чтобы найти записи, в которых все слова присутствуют в столбце Column1.

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

0

Ваш запрос SQL выглядит следующим образом:

SELECT * FROM MyTable WHERE 
Column1 LIKE '%word1%'
AND Column1 LIKE '%word2%'
AND Column1 LIKE '%word3%'

В этом запросе используются операторы AND, что означает, что результаты будут включать только те записи, в которых Column1 содержит все три слова: word1, word2 и word3.

Если вам нужно, чтобы Column1 содержал хотя бы одно из этих слов, вам следует использовать оператор OR. Однако, согласно вашему изменению запроса, вы правильно указали, что необходимо использовать AND. Убедитесь, что это именно то, что требуется для вашего случая, так как результаты будут значительно отличаться при использовании OR вместо AND.

0

Чтобы выполнить поиск совпадений в SQL, вы можете использовать оператор INSTR для получения совпадений с подстрокой.

Если ваша цель — просто найти совпадение, то SQL-запрос будет выглядеть следующим образом:

SELECT * FROM MyTable WHERE INSTR('word1 word2 word3', Column1) <> 0

Для SQL Server аналогичный запрос может быть записан с использованием функции CHARINDEX:

SELECT * FROM MyTable WHERE CHARINDEX(Column1, 'word1 word2 word3', 1) <> 0

Если вам требуется точное совпадение, вы можете использовать следующий подход. Например, если у вас есть строки с разделителями, как в примере (';a;ab;ac;',';b;'), чтобы избежать частичных совпадений, вы можете вставить разделитель перед и после значений:

SELECT * FROM MyTable WHERE INSTR(';word1;word2;word3;', ';'||Column1||';') <> 0

Это гарантирует, что Column1 будет найден только как отдельное слово, а не как часть другого слова. Обратите внимание, что в SQL Server вам нужно будет применить другой синтаксис:

SELECT * FROM MyTable WHERE CHARINDEX(';' + Column1 + ';', ';word1;word2;word3;') <> 0

Таким образом, использование разделителей помогает добиться точного совпадения.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь