Pergunta

Eu tenho uma tabela que lista uma entrada de texto freet de uma pesquisa onde enterents foram autorizados a entrar suas respostas (em relação a cores que gostaria de ter em seu casamento)

Eu gostaria de escrever uma função SQL que reúne todas as informações desta coluna, e ordens conta a freqüência de cada palavra, ordenando o conjunto de resultados por esta contagem.

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

Eu gostaria que a tabela acima para ser ordenados da seguinte maneira

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

Eu posso tirar todas as palavras de lixo como "e" depois que a função foi executado. Alguém conhece algum boas funções que produzem este comportamento?

Foi útil?

Solução

Ok isso funciona um deleite. Em primeiro lugar uma função para separar os valores ...

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    

então eu simplesmente aplicá-lo à minha mesa ...

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

Ok, então eu fui OTT com meus tabelas aninhadas, mas eu já retirados todos os personagens porcaria, separado os valores e manteve uma execução total das palavras usadas com mais frequência.

Outras dicas

Você está principal problema é que você está perdendo uma função split no SQL Server.

Há uma uma amostra aqui que parece muito bom ..

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

Usando isso, você escrever uma proc armazenados ao longo das linhas de ...

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

Há provavelmente uma menos fugly maneira de fazer isso sem cursores, mas se é apenas algo que você necessidade de executar uma vez, e você está de mesa ou respostas não é fenomenalmente grande, então isso deve funcionar

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top