Можно ли использовать LIKE с набором строк вместо одного элемента? - PullRequest
1 голос
/ 23 апреля 2019

У меня есть список имен собственных (в таблице) и другая таблица с полем свободного текста.Я хочу проверить, содержит ли это поле какие-либо из собственных имен.Если бы это был только один, я мог бы сделать

WHERE free_text LIKE "%proper_name%"

, но как вы делаете это для всего списка?Есть ли лучшая строковая функция, которую я могу использовать со списком?

Спасибо

Ответы [ 2 ]

0 голосов
/ 23 апреля 2019

Ну, вы можете использовать LIKE в стандартном JOIN, но запрос, скорее всего, будет медленным, потому что он будет искать каждое собственное имя в каждом free_text.

Например, если в списке 10 собственных имен и определенное значение free_text содержит имя, сервер продолжит обработку остальных 9 имен.

Вот запрос:

SELECT  -- DISTINCT
    free_text_table.*
FROM
    free_text_table
    INNER JOIN proper_names_table ON free_text_table.free_text LIKE proper_names_table.proper_name
;

Если определенное значение free_text содержит несколько собственных имен, эта строка будет возвращаться несколько раз, поэтому вам может понадобиться добавить DISTINCT к запросу. Это зависит от того, что вам нужно.


Можно использовать LATERAL JOIN, чтобы избежать декартова произведения (где каждая строка в free_text_table сравнивается с каждой строкой в ​​proper_names_table). Конечный результат может быть быстрее, чем простой вариант. Это зависит от вашего распределения данных.

Вот синтаксис SQL Server.

SELECT
    free_text_table.*
FROM
    free_text_table
    CROSS APPLY
    (
        SELECT TOP(1)
            proper_names_table.proper_name
        FROM proper_names_table
        WHERE free_text_table.free_text LIKE proper_names_table.proper_name
        -- ORDER BY proper_names_table.frequency
    ) AS A
;

Здесь нам не нужно DISTINCT, будет не более одной строки в результате для каждой строки из free_text_table (один или ноль). Оптимизатор должен быть достаточно умен, чтобы прекратить чтение и обработку proper_names_table, как только будет найдено первое совпадение из-за предложения TOP(1).

Если вы также можете каким-то образом упорядочить свои собственные имена и поставить те, которые, скорее всего, будут найдены первыми, тогда запрос, скорее всего, будет быстрее, чем простой JOIN. (Добавьте подходящее предложение ORDER BY в подзапрос).

0 голосов
/ 23 апреля 2019

Нет, like не имеет такой возможности.

Многие базы данных поддерживают регулярные выражения, которые позволяют вам делать то, что вы хотите.Например, в Postgres это формулируется как:

where free_text ~ 'name1|name2|name3'

Многие базы данных также имеют возможности полнотекстового поиска, которые ускоряют такой поиск.

Обе возможности очень специфичны для используемой вами базы данных..

...