2009-05-19 1 views
3

У меня есть таблица, которая перечисляет вход Freet текста из опроса, где enterents были разрешено вводить свои ответы (относительно цвета они хотели бы иметь в своей свадьбе)Sql функции сервера для отображения частоты слов в столбце

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

Response 
-------- 
Red and White 
green 
White and blue 
Blue 
Dark blue 

Я хотел бы таблицу выше, чтобы быть упорядочены следующим образом

Response Frequency 
-------- --------- 
Blue  3 
White  2 
And  2 
Red  1 
Green  1 

я могу лишить все слова, как мусор «и» после того, как функция запуска. Кто-нибудь знает какие-либо хорошие функции, которые производят такое поведение?

ответ

4

Хорошо, это работает. Во-первых, функция для разделения значений ...

Alter Function dbo.SeparateValues  

( 
@data VARCHAR(MAX),  
@delimiter VARCHAR(10)  
)  
RETURNS  
@tbldata TABLE(col VARCHAR(MAX))  
As  
--Declare @data VARCHAR(MAX) ,@delimiter VARCHAR(10)  
--Declare @tbldata TABLE(col VARCHAR(10))  
--Set @data = 'hello,how,are,you?,234234'  
--Set @delimiter = ','  
--DECLARE @tbl TABLE(col VARCHAR(10))  
Begin  
DECLARE @pos INT  
DECLARE @prevpos INT  
SET @pos = 1  
SET @prevpos = 0  

WHILE @pos > 0  
BEGIN  
SET @pos = CHARINDEX(@delimiter, @data, @prevpos+1)  
if @pos > 0  
INSERT INTO @tbldata(col) VALUES(LTRIM(RTRIM(SUBSTRING(@data, @prevpos+1, @[email protected]))))  
else  
INSERT INTO @tbldata(col) VALUES(LTRIM(RTRIM(SUBSTRING(@data, @prevpos+1, len(@data)[email protected]))))  
SET @prevpos = @pos  
End  

RETURN  
END  

тогда я просто применить его к моему столу ...

Select Count(*), sep.Col FROM (
     Select * FROM (
      Select value = Upper(RTrim(LTrim(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(response, ',', ' '), '.', ' '), '!', ' '), '+', ' '), ':', ' '), '-', ' '), ';', ' '), '(', ' '), ')', ' '), '/', ' '), '&', ''), '?', ' '), ' ', ' '), ' ', ' ')))) FROM Responses 
     ) easyValues 
     Where value <> '' 
    ) actualValues 
    Cross Apply dbo.SeparateValues(value, ' ') sep 
    Group By sep.Col 
    Order By Count(*) Desc 

Хорошо, так что я пошел OTT со своими вложенными таблицами, но я разделили все символы дерьма, разделили значения и сохранили общее количество наиболее часто используемых слов.

+0

Производительность этого, вероятно, ужасная с многочисленными операциями замены и очень медленной функцией SeparateValues. Попробуйте использовать что-то вроде этого для разделения строк по крайней мере: http://sqlblog.com/blogs/adam_machanic/archive/2009/04/28/sqlclr-string-splitting-part-2-even-faster-even-more- scalable.aspx – devinbost

1

Основная проблема заключается в том, что в SQL Server отсутствует функция разделения.

Theres образец один здесь, который выглядит довольно хорошо ..

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=50648

С помощью этого, вы пишете хранимую процедуру вдоль линий ...

CREATE TABLE #Temp (Response nvarchar(50), Frequency int) 

DECLARE @response nvarchar(100) 
DECLARE db_cursor CURSOR FOR 
SELECT response FROM YourTable 

OPEN db_cursor 
FETCH NEXT FROM db_cursor INTO @response 

WHILE @@FETCH_STATUS = 0 
BEGIN 
     /* Pseudo Code */ 
     --Split @Response 
     --Iterate through each word in returned list 
     --IF(EXISTS in #TEMP) 
     -- UPDATE THAT ROW & INCREMENT THE FREQUENCY 
     --ELSE 
     -- NEW WORD, INSERT TO #Temp WITH A FREQUENCY OF 1 

     FETCH NEXT FROM db_cursor INTO @response 
END 

SELECT * FROM #Temp 

Theres, вероятно, меньше, быстрый способ сделать это без курсоров, но если это всего лишь то, что вам нужно запустить один раз, а вы стол или ответы не феноменально большие, тогда это должно работать

+0

Спасибо - я хотел бы упомянуть, - я отказываюсь cursours, я буду смотреть на то, чтобы его КТР! – digiguru

+0

Если вы находитесь на SQL 2005 или 2008, вы также можете посмотреть на это как функцию CLR в .NET, расщепление/повторение/подсчет, вероятно, будет намного проще на языке .NET. –

0
DECLARE @phrases TABLE (id int, phrase varchar(max)) 
INSERT @phrases values 
(1,'Red and White' ), 
(2,'green'   ), 
(3,'White and blue'), 
(4,'Blue'   ), 
(5,'Dark blue'  ); 

SELECT word, COUNT(*) c 
FROM @phrases 
CROSS APPLY (SELECT CAST('<a>'+REPLACE(phrase,' ','</a><a>')+'</a>' AS xml) xml1) t1 
CROSS APPLY (SELECT n.value('.','varchar(max)') AS word FROM xml1.nodes('a') x(n)) t2 
GROUP BY word 
word   freq 
----------- ----------- 
and   2 
blue  3 
Dark  1 
green  1 
Red   1 
White  2 
Смежные вопросы