2009-05-19 8 views
3

私は(彼らは彼らの結婚式にしたいと思います色について)enterentsは、それらの応答に入ることを許可された調査からfreetテキスト入力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を行ってきましたが、私はしました値を分けて、最も頻繁に使用される言葉の連続した合計を保った。

+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で分割機能が不足していることです。

は、おそらくあまりなかなか良さそうです、ここでサンプル1 ..それを使用して

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のTheresの醜い方法は、カーソルなしでこれを行うが、それはちょうどあなたが が一度実行する必要があり、あなたはテーブルまたはレスポンスが驚くほど大きくない場合は、これが動作するはずです

+0

おかげで - 私が言及している必要があります - 私はcursoursを拒否し、私はそれをCTEを作るを見てみましょう! – digiguru

+0

SQL 2005または2008を使用している場合は、これを.NETのCLR関数として記述することもできます。分割/反復/カウントはおそらく.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 
関連する問題