我有一张表格,其中列出了调查中的一个自由文本输入,其中允许进入他们的回答(关于他们希望在婚礼中使用的颜色)
我想编写一个sql函数来收集此列中的所有信息,并且order会计算每个单词的频率,按此计数对结果集进行排序。
Response
--------
Red and White
green
White and blue
Blue
Dark blue
我想按照以下方式订购上表
Response Frequency
-------- ---------
Blue 3
White 2
And 2
Red 1
Green 1
我可以在函数运行后删除所有垃圾词,如“和”。有谁知道产生这种行为的任何好功能?
答案 0 :(得分: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, @pos-@prevpos-1))))
else
INSERT INTO @tbldata(col) VALUES(LTRIM(RTRIM(SUBSTRING(@data, @prevpos+1, len(@data)-@prevpos))))
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 :(得分: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
如果没有游标,这可能是一种不那么简单的方法,但如果它只是你的东西 需要运行一次,你是桌子或响应不是非常大,那么这应该工作
答案 2 :(得分:1)
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