2009-05-19 130 views
3

我有一個列出從那裏enterents被允許進入他們的反應的調查中孚瑞特文本輸入(關於顏色,他們希望在他們的婚禮)SQL Server的功能

表我想編寫一個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與我的嵌套表格,但我去掉所有垃圾字符,分開這些值並保持最常使用的單詞總數。

1

您的主要問題是您在SQL Server中缺少分割函數。

即使世界一個樣本一個在這裏,看起來很不錯..

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 

即使世界可能不太fugly的方式來做到這一點沒有遊標,但如果它只是你需要運行一次,而你是表或響應不是很大,那麼這應該工作

+0

謝謝 - 我應該提到 - 我拒絕cursours,我將看看使其CTE! – digiguru 2009-05-19 10:41:44

+0

如果你使用的是SQL 2005或2008,你也可以把它寫成.NET中的CLR函數,在.NET語言中分割/迭代/計數可能會更容易 – 2009-05-19 11:04:59

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