2011-10-06 46 views
1

只是一個探索性問題,看看是否有人做過這個或者如果實際上它是完全可能的。TSQL - 查詢表格列以標記標籤雲的熱門詞

我們都知道標籤雲是什麼,通常標籤雲是由分配標籤的人創建的。在SQL Server的當前功能中,是否有可能通過查看特定列中的數據並獲取熱門詞彙,在表中添加或更新記錄時通過觸發器自動創建此功能?

與此問題類似:How can I get the most popular words in a table via mysql?。但是,那是MySQL而不是MSSQL。

在此先感謝。 詹姆斯

+1

你需要使用字符串操作每個森泰斯轉換爲一組單詞。如果你創建一個表值函數,它接受一個字符串並輸出一個字表,然後你可以使用'myData CROSS APPLY myFunction(myTable.sentance)',然後使用GROUP BY來計算一切。確切地說需要什麼規則來打破一個單獨的單詞,我會留給你或其他:) – MatBailie

回答

6

這裏是解析分隔字符串好位爲行:
http://anyrest.wordpress.com/2010/08/13/converting-parsing-delimited-string-column-in-sql-to-rows/

http://www.sqlteam.com/article/parsing-csv-values-into-multiple-rows

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

T-SQL: Opposite to string concatenation - how to split string into multiple records

如果要分析所有的話,你可以使用空格作爲你的分隔符,然後你會得到每一個單詞的一行。

接下來,您將只需選擇結果集GROUP荷蘭國際集團由字和聚集COUNT

訂購您的結果和你的存在。

+0

正是我需要的,謝謝。當涉及到事物的性能方面時,我們究竟在看什麼? – jamesmhaley

+0

@ sparkyfied的表現將會非常糟糕。如果您有多行,並且您將每個行解析到臨時表中,則光標可能需要一段時間。幸運的是,你不需要經常製作標籤雲。 – Matthew

+0

因此,當管理員添加記錄或更新行時,最佳選擇是在觸發器上? – jamesmhaley

1

IMO,設計方法是什麼讓這很難。僅僅因爲您允許用戶分配標籤並不意味着標籤必須作爲單個分隔的單詞列表存儲。您可以標準化結構成類似:

Create Table Posts (Id ... not null primary key) 
Create Table Tags(Id ... not null primary key, Name ... not null Unique) 
Create Table PostTags 
    (PostId ... not null References Posts(Id) 
    , TagId ... not null References Tags(Id)) 

現在,你的問題就變得簡單:

Select T.Id, T.Name, Count(*) As TagCount 
From PostTags As PT 
    Join Tags As T 
     On T.Id = PT.TagId 
Group By T.Id, T.Name 
Order By Count(*) Desc 

如果硬要存儲標籤作爲分隔值,那麼唯一的辦法就是對他們的分隔符分割值通過編寫自定義拆分功能,然後做你的計數。底部是Split功能的一個例子。有了它,您的查詢看起來是這樣的(用逗號分隔符):

Select Tag.Value, Count(*) As TagCount 
From Posts As P 
    Cross Apply dbo.Split(P.Tags, ',') As Tag 
Group By Tag.Value 
Order By Count(*) Desc 

拆分功能:

Create Function [dbo].[Split] 
( 
    @DelimitedList nvarchar(max) 
    , @Delimiter nvarchar(2) = ',' 
) 
RETURNS TABLE 
AS 
RETURN 
    (
    With CorrectedList As 
     (
     Select Case When Left(@DelimitedList, DataLength(@Delimiter)/2) <> @Delimiter Then @Delimiter Else '' End 
      + @DelimitedList 
      + Case When Right(@DelimitedList, DataLength(@Delimiter)/2) <> @Delimiter Then @Delimiter Else '' End 
      As List 
      , DataLength(@Delimiter)/2 As DelimiterLen 
     ) 
     , Numbers As 
     (
     Select TOP (Coalesce(Len(@DelimitedList),1)) Row_Number() Over (Order By c1.object_id) As Value 
     From sys.objects As c1 
      Cross Join sys.columns As c2 
     ) 
    Select CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen As Position 
     , Substring (
        CL.List 
        , CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen  
        , Case 
         When CharIndex(@Delimiter, CL.list, N.Value + 1)        
          - CharIndex(@Delimiter, CL.list, N.Value) 
          - CL.DelimiterLen < 0 Then Len(CL.List) 
         Else CharIndex(@Delimiter, CL.list, N.Value + 1)        
          - CharIndex(@Delimiter, CL.list, N.Value) 
          - CL.DelimiterLen 
         End 
        ) As Value 
    From CorrectedList As CL 
     Cross Join Numbers As N 
    Where N.Value < Len(CL.List) 
     And Substring(CL.List, N.Value, CL.DelimiterLen) = @Delimiter 

)