funzione di server SQL per la visualizzazione di frequenza delle parole in una colonna
-
22-08-2019 - |
Domanda
Ho una tabella che elenca un input di testo freet da un sondaggio in cui enterents sono stati autorizzati a entrare nelle loro risposte (per quanto riguarda i colori che vorrebbero avere nel loro matrimonio)
Vorrei scrivere una funzione SQL che raccoglie tutte le informazioni da questa colonna, e gli ordini conta la frequenza di ogni parola, ordinando il set di risultati da questo conteggio.
Response
--------
Red and White
green
White and blue
Blue
Dark blue
Vorrei che la tabella di cui sopra devono essere ordinati come segue
Response Frequency
-------- ---------
Blue 3
White 2
And 2
Red 1
Green 1
posso spogliare tutte le parole spazzatura come "e" dopo la funzione è eseguito. Qualcuno sa qualsiasi buone funzioni che producono questo comportamento?
Soluzione
Va bene questo funziona a meraviglia. In primo luogo una funzione per separare i valori ...
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
poi ho appena applico al mio tavolo ...
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
Va bene, così sono andato con i miei OTT tabelle nidificate, ma ho spogliato fuori tutti i personaggi merda, separato i valori e mantenuto un totale corrente delle parole più frequentemente utilizzate.
Altri suggerimenti
Sei problema principale è che ti manca una funzione split in SQL Server.
C'è un campione di uno qui che sembra piuttosto buono ..
http://www.sqlteam.com/forums/topic.asp ? topic_id = 50648
Utilizzando che, si scrive un proc memorizzato lungo le linee di ...
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
C'è probabilmente un modo meno fugly di farlo senza cursori, ma se è solo qualcosa che si necessario eseguire una volta, e tu sei tavolo o risposte non è fenomenale grande, allora questo dovrebbe funzionare
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