只是一个探索性的问题,看看是否有人这样做过,或者实际上是否有可能。
我们都知道标签云是什么,通常,标签云是由分配标签的人创建的。是否有可能在 SQL Server 的当前功能中自动创建它,可能通过在表添加或更新记录时通过触发器,通过查看特定列中的数据并获取流行词?
它类似于这个问题:如何通过mysql获取表中最受欢迎的单词?. 但是,那是 MySQL 而不是 MSSQL。
提前致谢。詹姆士
只是一个探索性的问题,看看是否有人这样做过,或者实际上是否有可能。
我们都知道标签云是什么,通常,标签云是由分配标签的人创建的。是否有可能在 SQL Server 的当前功能中自动创建它,可能通过在表添加或更新记录时通过触发器,通过查看特定列中的数据并获取流行词?
它类似于这个问题:如何通过mysql获取表中最受欢迎的单词?. 但是,那是 MySQL 而不是 MSSQL。
提前致谢。詹姆士
这是将分隔字符串解析为行的一个好方法: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:与字符串连接相反 - 如何将字符串拆分为多条记录
如果要解析所有单词,可以使用空格 ' ' 作为分隔符,然后每个单词都有一行。
接下来,您只需GROUP
按单词选择结果集并聚合COUNT
订购你的结果,你就在那里。
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
如果您坚持将标签存储为分隔值,那么唯一的解决方案是通过编写自定义拆分函数在其分隔符上拆分值,然后进行计数。底部是拆分函数的示例。有了它,您的查询将类似于(使用逗号分隔符):
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
)