2015-09-17 2 views
2

Я пытаюсь использовать оператор SELECT для получения числа совпадений из моей базы данных, число совпадений больше 0, но я также хочу получить максимальные совпадения. Поэтому, если есть совпадения 1,2 и 3, я просто хочу совпадений 3. После того, как я добавил в часть «И» совпадения «= MAX (« соответствует »), по какой-то причине он прекратил получать результаты. Он получал результаты, прежде чем я добавил. Мне интересно, что я сделал не так, и как это исправить. Благодарю.Получение максимальных совпадений из базы данных с помощью оператора select

SELECT input, response, 
(input LIKE '% you %') + 
(input LIKE '% are %') + 
(input LIKE '% here %') 
AS 'matches' 
FROM allData 
HAVING `matches` > 0 
AND 'matches' = MAX('matches') 
+0

Перед тем, как спички, вы не можете знать, что является не более, так что это нормально, если это не работает. Я бы получил все совпадения, сгруппированные по совпадениям, а затем сортировку по счету или поиск макс в этой группе, а затем выбор необходимых полей в них. – CntkCtn

+0

@CntkCtn Пожалуйста, попробуйте ответить. – jessica

+0

Чтобы ответить, мне нужна БД и сделайте тесты, чтобы быть уверенным, что я правильно даю ответ, и у меня его нет на данный момент. Я буду держать его в качестве комментария. – CntkCtn

ответ

2

Вы отметили mysql в своем вопросе. Это немного неудачно, потому что на вопрос можно ответить более чисто для почти любой другой реляционной базы данных, популярной сегодня, чем это может быть для MySQL. Тем не менее, с MySQL вы можете сделать это следующим образом:

SELECT 
    input, 
    response, 
    (input LIKE '% you %') + 
    (input LIKE '% are %') + 
    (input LIKE '% here %') 
    AS matches 
FROM allData 
HAVING matches > 0 
    AND matches = (
     SELECT MAX(
     (input LIKE '% you %') + 
     (input LIKE '% are %') + 
     (input LIKE '% here %')) 
     FROM allData 
    ) 
+0

Можно ли сделать так, чтобы, если он находит 2 удара одного и того же слова, совпадения увеличиваются на 2 вместо одного? – jessica

+0

Привет @jessica, см. Мой отредактированный ответ. Вы можете использовать ту же технику в запросе Джона. –

+0

@jessica, Thorsten's - довольно умный способ подсчета совпадений одного и того же шаблона. Обратите внимание, однако, что в этом отношении и в других случаях у вас есть проблема с пробелами по обе стороны от шаблонов LIKE. Они обеспечивают, чтобы вы соответствовали только полным словам, но они также * предотвращали * вас от совпадения слов, которые немедленно предшествовали или сразу же сопровождались пунктуацией. Что касается подсчета, они будут вмешиваться в подсчет удвоенных слов («вы здесь, здесь»). –

0

Если вы хотите, чтобы все строки с максимальным спичек, то один из способов является использование подзапроса:

SELECT input, response, 
     (input LIKE '% you %') + (input LIKE '% are %') + (input LIKE '% here %') AS matches 
FROM allData 
HAVING matches = (SELECT (input LIKE '% you %') + (input LIKE '% are %') + (input LIKE '% here %') as matches 
        FROM allData 
        HAVING `matches` > 0 
        ORDER BY matches DESC 
        LIMIT 1 
       ) 

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

SELECT t.* 
FROM (SELECT input, response, 
      (input LIKE '% you %') + (input LIKE '% are %') + (input LIKE '% here %') AS matches, 
      (@m := if(@m < (input LIKE '% you %') + (input LIKE '% are %') + (input LIKE '% here %'), 
         (input LIKE '% you %') + (input LIKE '% are %') + (input LIKE '% here %'), 0) 
     FROM allData CROSS JOIN (SELECT @m := 0) params 
    ) t 
WHERE matches = @m; 

Используется «функция», которую подзапрос оценивается перед внешним запросом, поэтому вы можете установить значение в подзапросе, а затем использовать его во внешнем where.

+0

Неизвестный столбец 'matches' in 'список полей – jessica

+0

Можете ли вы удалить «четвёрки» рядом с совпадениями по всему запросу. – CntkCtn

+0

Можно ли сделать так, чтобы, если он находит 2 удара одного и того же слова, совпадения увеличиваются на 2 вместо одного? – jessica

1

Просто используйте ORDER BY с LIMIT, чтобы получить лучший результат только:

SELECT input, response, 
(input LIKE '% you %') + 
(input LIKE '% are %') + 
(input LIKE '% here %') 
AS matches 
FROM allData 
HAVING matches > 0 
ORDER BY matches DESC LIMIT 1; 

В случае равенства вы получите только один случайный лучший показатель хоть. Если вы хотите все, тогда перейдите к ответу Джона Боллинджера.

SQL скрипт: http://sqlfiddle.com/#!9/1ece1/3.


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

SELECT input, response, 
((length(input) - length(replace(input, ' you ', '')))/length(' you ')) + 
((length(input) - length(replace(input, ' are ', '')))/length(' are ')) + 
((length(input) - length(replace(input, ' here ', '')))/length(' here ')) 
    AS matches 
FROM allData 
HAVING matches > 0 
ORDER BY matches DESC LIMIT 1; 

SQL скрипку: http://sqlfiddle.com/#!9/f680b/3.

И еще одна скрипка, чтобы показать, как это работает: http://sqlfiddle.com/#!9/f680b/1.


Вот запрос Джона с той же техникой:

SELECT input, response, 
((length(input) - length(replace(input, ' you ', '')))/length(' you ')) + 
((length(input) - length(replace(input, ' are ', '')))/length(' are ')) + 
((length(input) - length(replace(input, ' here ', '')))/length(' here ')) 
    AS matches 
FROM allData 
HAVING matches > 0 
AND matches = 
(
    SELECT MAX(
    ((length(input) - length(replace(input, ' you ', '')))/length(' you ')) + 
    ((length(input) - length(replace(input, ' are ', '')))/length(' are ')) + 
    ((length(input) - length(replace(input, ' here ', '')))/length(' here ')) 
) 
    FROM allData 
); 

SQL скрипка: http://sqlfiddle.com/#!9/57098/1.


Что касается вас, вы, вы правы; удалив «ты» из строки, я беру с собой пространство, необходимое для поиска следующего «ты». Вы можете легко обойти это, хотя, заменив каждое пространство двумя в input перед выполнением операции. И вы, возможно, захотите добавить ведущее и тренировочное пространство. (Возможно, вы даже захотите применить LOWER() к строке, чтобы найти «вы», а также «вы».)

Так заменить

FROM allData 

с

FROM 
(
    select 
    replace(concat(' ', input, ' '), ' ', ' ') as input, 
    response 
    from allData 
) prepared 
+0

Можно ли сделать так, чтобы, если он находит 2 удара одного и того же слова, совпадения увеличиваются на 2 вместо одного? – jessica

+0

Да, это так. Ему нужна только математика. Я добавил это к своему ответу. –

+0

Ах. Один из результатов вернулся 1.1667? Как это возможно? – jessica

Смежные вопросы