2010-07-31 58 views
6

我在我的數據庫中包含一個包含自由文本字段列的表。使用SQL計算TF-IDF

我想知道每個單詞在所有行上出現的頻率,或者甚至可以爲所有單詞計算一個TF-IDF,其中我的文檔是該行每個行的值。

是否有可能使用SQL查詢來計算這個值?如果不是或者有一種更簡單的方法,你可以請我指導它嗎?

非常感謝,

喬恩

+0

什麼RDBMS和版本? – 2010-07-31 09:43:46

+0

微軟Sql Server 2008 – Jon 2010-07-31 10:11:15

回答

5

在SQL Server 2008中根據你的需要,你可以申請全文索引然後查詢sys.dm_fts_index_keywordssys.dm_fts_index_keywords_by_documenttable valued functions以獲得發生次數。

編輯:其實即使沒有創建持久全文索引,你仍然可以利用解析器

WITH testTable AS 
(
SELECT 1 AS Id, N'how now brown cow' AS txt UNION ALL 
SELECT 2, N'she sells sea shells upon the sea shore' UNION ALL 
SELECT 3, N'red lorry yellow lorry' UNION ALL 
SELECT 4, N'the quick brown fox jumped over the lazy dog' 
) 

SELECT display_term, COUNT(*) As Cnt 
FROM testTable 
CROSS APPLY sys.dm_fts_parser('"' + REPLACE(txt,'"','""') + '"', 1033, 0,0) 
WHERE TXT IS NOT NULL 
GROUP BY display_term 
HAVING COUNT(*) > 1 
ORDER BY Cnt DESC 

返回

display_term     Cnt 
------------------------------ ----------- 
the       3 
brown       2 
lorry       2 
sea       2 
+0

你搖滾!!!這是一個驚人的解決方案,需要我花幾天才能找到。 (我只需要添加一行來過濾帶有空文本的字段,否則會返回一個錯誤「空或全空全文謂詞」,我添加的行是「WHERE tbl1.txt_field!='」「'」) – Jon 2010-07-31 18:48:42

+0

謝謝,我會將其納入我的答案。 – 2010-07-31 19:19:04

2

解決方案SQL Server 2008中:

這裏是表:

CREATE TABLE MyTable (id INT, txt VARCHAR(MAX)); 

這裏是SQL查詢:

SELECT sum(case when TSplitted.txt_word = 'searched' then 1 else 0 end) as cnt_searched 
    , count(*) as cnt_all 
FROM MyTable MYT 
INNER JOIN Fn_Split(MYT.id,' ',MYT.txt) TSplitted on MYT.id=TSplitted.id 

這是 表值函數Fn_Split(@id INT,@separator VARCHAR(32),@string VARCHAR(MAX))(從here拍攝):

CREATE FUNCTION Fn_Split (@id int, @separator VARCHAR(32), @string VARCHAR(MAX)) 

RETURNS @t TABLE 
    (
     ret_id INT 
     ,txt_word VARCHAR(MAX) 
    ) 
AS 
    BEGIN 
     DECLARE @xml XML 
     SET @XML = N'<root><r>' + REPLACE(@s, @separator, '</r><r>') + '</r></root>' 

     INSERT INTO @t(ret_id, val) 
     SELECT @id, r.value('.','VARCHAR(5)') as Item 
     FROM @xml.nodes('//root/r') AS RECORDS(r) 

     RETURN 
    END