2009-05-19 2 views
3

나는 (그들이 그들의 결혼식에하고 싶은 색상에 대한) enterents가 자신의 응답을 입력 할 수 있었다 설문 조사에서 Freet의 텍스트 입력는 SQL 서버 기능

를 나열하는 테이블이 이 열의 모든 정보를 수집하는 SQL 함수를 작성하고 각 단어의 빈도를 계산하여이 수로 결과 세트를 정렬합니다. 내가 "와"기능이 실행 된 후 같은 모든 쓰레기 단어를 제거 할 수

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

을 다음과 같이

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

나는 위의 표를 싶습니다 주문할 수 있습니다. 누구든지이 동작을 생성하는 좋은 기능을 알고 있습니까?

답변

4

좋습니다. 첫째 기능은

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 

가 좋아 ...

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  

다음 난 그냥 내 테이블에 적용 ... 값을 구분하는, 그래서 난 내 중첩 된 테이블 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의 분할 기능이 누락 된 것이 주된 문제입니다.

아마 덜 꽤 좋아 보인다 여기에 샘플 하나 .. 그 사용

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

, 당신의 라인을 따라 proc 디렉토리에 저장 쓰기

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