función de servidor SQL para la visualización de la frecuencia de palabras en una columna
-
22-08-2019 - |
Pregunta
Tengo una tabla que muestra una entrada de texto Freet de una encuesta donde se les permitió enterents para entrar en sus respuestas (en cuanto a los colores que les gustaría tener en su boda)
Me gustaría escribir una función SQL que recoge toda la información de esta columna, y las órdenes que cuenta la frecuencia de cada palabra, de ordenar el conjunto de resultados de este conteo.
Response
--------
Red and White
green
White and blue
Blue
Dark blue
Me gustaría la tabla anterior para ser ordenados como sigue
Response Frequency
-------- ---------
Blue 3
White 2
And 2
Red 1
Green 1
puedo quitar todas las palabras de basura como "y" después de la función se ha ejecutado. ¿Alguien sabe alguna buenas funciones que producen este comportamiento?
Solución
Está bien esto funciona un convite. En primer lugar una función de separar los 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
entonces sólo lo aplico a mi 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
De acuerdo, así que fui con mis OTT tablas anidadas, pero he despojado a cabo todos los caracteres basura, separé los valores y se mantiene un total acumulado de las palabras más frecuentemente utilizadas.
Otros consejos
Usted es principal problema es que se está perdiendo una función de división en SQL Server.
Hay una muestra de uno aquí que se ve muy bien ..
http://www.sqlteam.com/forums/topic.asp ? topic_id = 50648
Uso de eso, se escribe un procedimiento almacenado en la línea 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
Theres probablemente una manera menos fugly de hacer esto sin cursores, pero si es sólo algo que se necesita ejecutar una vez, y eres mesa o respuestas no es extraordinariamente grande, entonces esto debería 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