2009-07-07 6 views
5

У меня есть таблица с полем varchar (255). Я хочу получить (через запрос, функцию или SP) количество вхождений каждого слова в группе строк из этой таблицы.Подсчет слов в столбце таблицы

Если есть 2 строки с этими полями:

 
"I like to eat bananas" 
"I don't like to eat like a monkey" 

Я хочу, чтобы получить

 
    word | count() 
    --------------- 
    like 3 
    eat 2 
    to 2 
    i  2 
    a  1 

Любая идея? Я использую MySQL 5.2.

+0

Возможный дубликат [Подсчитать частоту каждого слова] (http://stackoverflow.com/questions/22410458/count-the-frequency-of-each-word). Этот вопрос стареет, но в другом вопросе было принято решение. – RandomSeed

ответ

1

Я бы порекомендовал не делать этого в SQL вообще. Вы загружаете БД с чем-то, на что не лучше. Выбор группы строк и выполнение вычисления частоты на стороне приложения будет проще в реализации, будет работать быстрее и будет поддерживаться с меньшим количеством проблем/головных болей.

+0

Действительно, разве не разумнее запускать его как хранимую процедуру? или функции ?. Я всегда думал, что разгрузка таких вычислений на БД лучше. –

+1

Согласен, нет никакого способа сделать это, используя обычный SQL. Вы можете написать хранимую процедуру, чтобы сделать это, используя временную таблицу и модифицированную версию одного из методов в этой статье: http://www.sommarskog.se/arrays-in-sql-2000.html (это для SQL Server 2000, но можно легко адаптироваться к диалоговому диалогу MySQL). Тем не менее, проблема по-прежнему заключается в том, что вы выходите за пределы «зоны комфорта» SQL, делая это –

+0

. Вы, безусловно, можете сделать это в SP, используя несколько проходов над набором данных и извлечением каждое слово с регулярным выражением, затем помещая результаты в таблицу temp и итерацию по ней и так далее. Но это довольно сложно, его будет сложно писать и поддерживать, и я бы сказал, что техническое обслуживание еще более важно, чем писать его в первую очередь. DBs хороши для того, для чего они предназначены для хранения/чтения/записи реляционных данных. Заставляя их вычислять вещи, это просто субоптимальный дизайн и в конечном итоге вернется как много PITA. –

-1

Я думаю, вы пытаетесь сделать слишком много с SQL, если все слова находятся в одном поле каждой строки. Я рекомендую выполнять обработку/подсчет текста с вашим приложением после захвата текстовых полей из db.

+0

Действительно, разве не разумнее запускать его как хранимую процедуру? или функции ?. Я всегда думал, что разгрузка таких вычислений на БД лучше. –

0

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

+0

Да, но проблема в том, что мне нужно в области пользователя (FK в таблице со строкой, которую мне нужно разбор), используя таблицу соединений между словом, фразой и пользователем, кажется, немного больше, чем убить нет? –

0

Вы можете попробовать этот извращенный-а-поодаль:

SELECT 
(LENGTH(field) - LENGTH(REPLACE(field, 'word', '')))/LENGTH('word') AS `count` 
ORDER BY `count` DESC 

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

3

@Elad Meidar, мне нравится ваш вопрос, и я нашел решение:

SELECT SUM(total_count) as total, value 
FROM (

SELECT count(*) AS total_count, REPLACE(REPLACE(REPLACE(x.value,'?',''),'.',''),'!','') as value 
FROM (
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(t.sentence, ' ', n.n), ' ', -1) value 
    FROM table_name t CROSS JOIN 
(
    SELECT a.N + b.N * 10 + 1 n 
    FROM 
    (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a 
    ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b 
    ORDER BY n 
) n 
WHERE n.n <= 1 + (LENGTH(t.sentence) - LENGTH(REPLACE(t.sentence, ' ', ''))) 
ORDER BY value 

) AS x 
GROUP BY x.value 

) AS y 
GROUP BY value 

Вот полная рабочей скрипка: http://sqlfiddle.com/#!2/17481a/1

Сначала мы делаем запрос, чтобы извлечь все слова, как объяснено here по @peterm (следуйте его инструкциям, если вы хотите настроить общее количество обработанных слов). Затем мы преобразуем это в подзапрос, а затем получаем значение каждого слова, а затем сделаем еще один запрос в верхней части этого слова для GROUP BY не сгруппированных слов, в которых могут присутствовать сопровождающие знаки. т.е.: hello = привет! с REPLACE

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