2015-02-24 2 views
2

у меня есть этот запрос:Mysql выбрать на лучший матч с подобным

SELECT `id` FROM `accounts` 
WHERE AES_DECRYPT(`email`, :salt) = CONCAT_WS('@',:mailbox,:host) 
OR AES_DECRYPT(`email`, :salt) LIKE CONCAT('%',:host) 

У меня есть 2 записей в этой таблице:

id  email 
1  [email protected] 
2  [email protected] 

Когда я бегу этот вопрос так:

SELECT `id` FROM `accounts` 
WHERE AES_DECRYPT(`email`, '123') = CONCAT_WS('@','test','test.com') 
OR AES_DECRYPT(`email`, '123') LIKE CONCAT('%','test.com') 

Получаю это как результат:

id  email 
2  [email protected] 
1  [email protected] 

Вопрос: Что я хочу, так это: я хочу иметь наилучшее совпадение в качестве первого результата, не используя полнотекстовый поиск. Возможно ли это, если да, как я могу это сделать?

+0

что вы подразумеваете под лучшим матчем? –

+1

Когда я ищу [email protected], я хочу получить [email protected] в качестве первого результата. [email protected] имеет лучшее соответствие, чем [email protected] Я хочу, чтобы результат с совпадающими символами заканчивался сверху. – SheperdOfFire

+0

Извините, это похоже на странное правило для меня. Так [email protected] лучше, чем [email protected]? И [email protected] так же хорош, как [email protected] при поиске gmail? И [email protected] так же хорош, как [email protected]? Я думаю, вы должны уточнить свои правила, а затем вернуться сюда. –

ответ

0

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

SELECT `id` 
FROM `accounts` 
WHERE AES_DECRYPT(`email`, '123') = CONCAT_WS('@', 'test', 'test.com') OR 
     AES_DECRYPT(`email`, '123') LIKE CONCAT('%','test.com') 
ORDER BY ((AES_DECRYPT(`email`, '123') = CONCAT_WS('@', 'test', 'test.com')) + 
      (AES_DECRYPT(`email`, '123') LIKE CONCAT('%','test.com')) 
     ); 

Это будет работать на вашем примере.

+1

Спасибо, это действительно работает. – SheperdOfFire

0

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

SELECT `id` FROM `accounts` 
WHERE AES_DECRYPT(`email`, :salt) = CONCAT_WS('@',:mailbox,:host) 
OR AES_DECRYPT(`email`, :salt) LIKE CONCAT('%',:host) 
order by AES_DECRYPT(`email`, :salt) = CONCAT_WS('@',:mailbox,:host) desc; 

Здесь мы используем специальный MySQL. Логическое выражение, которое TRUE, приводит к 1. логическое выражение, которое соответствует значению ЛОЖЬ результатов в 0. В другом СУБД вы могли бы написать вместо этого:

order by 
case when AES_DECRYPT(`email`, :salt) = CONCAT_WS('@',:mailbox,:host) 
     then 1 else 0 end desc; 
0

Этот код должен соответствовать вам:

SELECT `id` FROM `accounts` 
    WHERE AES_DECRYPT(`email`, :salt) = CONCAT_WS('@',:mailbox,:host) 
    OR AES_DECRYPT(`email`, :salt) LIKE CONCAT('%',:host) 
    ORDER BY LENGTH(`email`) - LENGTH(REPLACE(`email`, :host, '')) - LENGTH(REPLACE(`email`, :mailbox, '')) DESC 
Смежные вопросы