2009-05-19 116 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