Подсчет частоты слов в запросе MySQL

Я работаю с базой данных с одной таблицей, состоящей из двух столбцов: целочисленного идентификатора слова и слова varchar. Таблица состоит из нескольких тысяч строк и была создана путем чтения большого количества текста программным путем и разбиения на пробелы, а затем выделения отдельных слов и вставки их в базу данных. Цель состоит в том, чтобы использовать этот словарь для чтения полнотекстовых сообщений в блогах, твитов и другого текстового контента и оценивать их релевантность.

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

Вот мой оператор выбора и попытка подсчитать частоту слов одновременно с подсчетом.

  select word, 
  count(word), 
  10*(((max(count(word))+1) - count(word))/(max(count(word))))
  from dictwords where length(word)>3 group by word having count(word)>35 
  order by count(word) desc;

Ошибка, возвращаемая mysql: «Недопустимое использование групповой функции». Ошибка 1111.

Можно ли сделать что-то подобное в одном выражении в mySQL? Или я должен разбить подсчет и оценку на два запроса, выполнив выборку и подав мою таблицу результатов в таблицу-заполнитель, а затем попытавшись ее оценить?


person Micah    schedule 13.11.2013    source источник
comment
MAX(COUNT - это проблема. Для получения дополнительной/лучшей помощи рассмотрите возможность предоставления правильных DDL и/или sqlfiddle ВМЕСТЕ С ЖЕЛАЕМЫМ РЕЗУЛЬТАТОМ.   -  person Strawberry    schedule 13.11.2013
comment
Я думаю, что его длина (слово) > 3 тоже неверна. Что он имеет в виду количество(слово)›3   -  person Andrew - OpenGeoCode    schedule 13.11.2013
comment
Он должен изменить количество (слово) в ВЫБЕРИТЕ слово, количество (слово) на: ВЫБЕРИТЕ слово, количество (слово) как частоту. Затем он мог бы заменить все ссылки на количество (слово) частотой. Гораздо читабельнее.   -  person Andrew - OpenGeoCode    schedule 13.11.2013


Ответы (2)


Я не думаю, что вы можете сделать это в одном запросе, поскольку вы пытаетесь найти, сколько раз встречается наиболее распространенное слово (я думаю). Это сработало для меня на тестовом наборе данных:

# get the number of times the most common word occurs
select @maxCount := count(word)
from temp 
where length(word)>3 
group by word 
having count(word)>10
order by count(word) desc
limit 1;

# now use that max value to calculate a score
select 
    word, 
    count(word) as wordCount,
    @maxCount as maxWordCount,
    10*(((@maxCount+1) - count(word))/(@maxCount)) as score
from temp 
where length(word)>3 
group by word 
having wordCount>10
order by wordCount desc;

sqlfiddle здесь, если хотите проверить, правильно ли я понял.

person boodle    schedule 13.11.2013
comment
Это очень похоже на ответ, который я получил, поигравшись с кодом — см. мой ответ ниже. - person Micah; 13.11.2013

  drop table if exists wordcount;

  create table wordcount(
   word varchar(50) primary key,
   wc   int     not null
  );

  insert into wordcount (word, wc)
  select word, count(word)
  from dictwords 
  where length(word)>3 
  group by word 
  having count(word)>35 
  order by count(word) desc;


  drop table if exists wordscore;
  create table wordscore(
  word  varchar(50) primary key,
  score int     not null);

  insert into wordscore (word, score)
  select word, (1-(10*(((max(wc)+1) - wc)/(max(wc)))))*10
  from wordcount 
  group by word;

пришлось создать таблицу попутно здесь - но я получил это пойти. Поскольку в необработанных данных я просматривал только слова с количеством экземпляров 35 или более, мы получаем оценку около 7-10 в этом наборе результатов.

person Micah    schedule 13.11.2013