Весовые условия в предложении WHERE оператора SQL - PullRequest
8 голосов
/ 18 февраля 2011

Я хочу найти записи, в которых определенное поле либо НАЧИНАЕТСЯ С некоторой строки (скажем, «ar») ИЛИ это поле содержит строку «ar».

Однако я считаю, что эти два условия различны, потому что я ограничиваю количество возвращаемых результатов до 10 и хочу, чтобы условие STARTS WITH было взвешено больше, чем условие CONTAINS.

Пример:

SELECT *
FROM Employees
WHERE Name LIKE 'ar%' OR Name LIKE '%ar%'
LIMIT 10

Загвоздка в том, что если есть имена, которые НАЧИНАЮТСЯ с "ar", то они должны быть предпочтительными. Единственный способ вернуть мне имя, которое просто содержит «ar», - это если МЕНЬШЕ, чем 10 имен, НАЧИНАЮЩИХСЯ с «ar»

Как я могу сделать это с базой данных MySQL?

Ответы [ 5 ]

11 голосов
/ 18 февраля 2011

Вам необходимо выделить их в 2 части и добавить тег предпочтения к результатам. 10 из каждого сегмента, затем объедините их и снова возьмите лучшие 10. Если в сегменте 1 будет 8 записей, то в сегменте 2 UNION ALL будет получено 2

.
SELECT *
FROM
(
SELECT *, 1 as Preferred
FROM Employees
WHERE Name LIKE 'ar%'
LIMIT 10
UNION ALL
SELECT *
FROM
(
    SELECT *, 2
    FROM Employees
    WHERE Name NOT LIKE 'ar%' AND Name LIKE '%ar%'
    LIMIT 10
) X
) Y
ORDER BY Preferred
LIMIT 10
4 голосов
/ 18 февраля 2011

Назначьте значение кода для результатов и отсортируйте по значению кода:

select
    *,
    (case when name like 'ar%' then 1 else 2 end) as priority
from
    employees
where
    name like 'ar%' or name like '%ar%'
order by
    priority
limit 10

Edit:

См. Ответ Ричарда aka cyberkiwi для более эффективного решения, если потенциально много совпадений.

1 голос
/ 18 февраля 2011

Мое решение:

SELECT *
FROM Employees
WHERE Name LIKE '%ar%'
ORDER BY instr(name, 'ar'), name
LIMIT 10

instr () ищет первое вхождение рассматриваемого шаблона. AR% придет раньше xxAR.

Это предотвращает:

  1. Сканирование таблицы следует выполнять только 1 раз. Объединения и производные таблицы делают 3. Первые два в столбцах отфильтровывают шаблоны, а затем третье в подмножестве, чтобы найти, где они равны - поскольку объединение отфильтровывает дубликаты.

  2. Дает истинную сортировку в зависимости от местоположения шаблона. Wx> xW> xxW> и т.д ...

0 голосов
/ 15 декабря 2015
SELECT *
FROM Employees
WHERE Name LIKE 'ar%' OR Name LIKE '%ar%'
ORDER BY LIKE 'ar%' DESC
LIMIT 10

Должен ли порядок работы двоичным образом истина / ложь для подобного и если index'ed должен извлечь выгоду из индекса

0 голосов
/ 18 февраля 2011

Попробуйте это (не иметь экземпляра MySQL, сразу доступного для тестирования):

SELECT * FROM
   (SELECT * FROM Employees WHERE Name LIKE 'ar%'
    UNION
    SELECT * FROM Employees WHERE Name LIKE '%ar%'
   )
 LIMIT 10

Возможно, есть лучшие способы сделать это, но это сразу же пришло в голову.

...