Как выполнить простой SQL-поиск с одним оператором по таблицам?

StackOverflow https://stackoverflow.com/questions/56334

  •  09-06-2019
  •  | 
  •  

Вопрос

Предположим, что существуют две таблицы: users и groups.

Как обеспечить «простой поиск», при котором пользователь вводит текст, а результаты содержат как пользователей, так и группы, имена которых содержат этот текст?

Результат поиска должен различать эти два типа.

Это было полезно?

Решение

Хитрость заключается в том, чтобы объединить UNION с буквальной строкой для определения типа возвращаемого объекта.В большинстве (?) случаев UNION ALL будет более эффективным и его следует использовать, если в подзапросах не требуются дубликаты.Следующего шаблона должно быть достаточно:

 SELECT "group" type, name
   FROM groups
  WHERE name LIKE "%$text%"
UNION ALL
 SELECT "user" type, name
   FROM users
  WHERE name LIKE "%$text%"

ПРИМЕЧАНИЕ:Я сам добавил ответ, потому что вчера столкнулся с этой проблемой, не смог найти хорошего решения и использовал этот метод.Если у кого-то есть лучший подход, пожалуйста, добавьте его.

Другие советы

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

Использование LIKE вызовет ряд проблем, поскольку потребуется сканирование таблицы каждый раз, когда компаратор LIKE начинается с %.Это заставляет SQL проверять каждую строку и работать побайтово со строкой, которую вы используете для сравнения.Хотя на старте это может быть нормально, это быстро приводит к проблемам с масштабированием.

Лучший способ справиться с этой проблемой — использовать полнотекстовый поиск.Хотя это будет более сложный вариант, он обеспечит лучшие результаты для очень больших баз данных.Затем вы можете использовать работоспособную версию примера, который дал вам Бобби Джек. UNION ALL ваши два набора результатов вместе и отобразите результаты.

Я бы предложил еще одно дополнение

 SELECT "group" type, name
   FROM groups
  WHERE UPPER(name) LIKE UPPER("%$text%")
UNION ALL
 SELECT "user" type, name
   FROM users
  WHERE UPPER(name) LIKE UPPER("%$text%")

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top