-
28-09-2019 - |
题
我有一个MSSQL 2005表:
[Companies](
[CompanyID] [int] IDENTITY(1,1) NOT NULL,
[Title] [nvarchar](128),
[Description] [nvarchar](256),
[Keywords] [nvarchar](256)
)
我想为该公司生成标签云。但是,我将所有关键字保存在一个由逗号隔开的一列中。关于如何通过大多数使用的关键字生成标签云的任何建议。每个公司可能有数百万公司大约十个关键字。
谢谢你。
解决方案
步骤1:将关键字分为正确的关系(表)。
CREATE TABLE Keywords (KeywordID int IDENTITY(1,1) NOT NULL
, Keyword NVARCHAR(256)
, constraint KeywordsPK primary key (KeywordID)
, constraint KeywordsUnique unique (Keyword));
步骤2:将公司和标签之间的多对多关系映射到一个单独的表格中,就像所有多对多关系:
CREATE TABLE CompanyKeywords (
CompanyID int not null
, KeywordID int not null
, constraint CompanyKeywords primary key (KeywordID, CompanyID)
, constraint CompanyKeyword_FK_Companies
foreign key (CompanyID)
references Companies(CompanyID)
, constraint CompanyKeyword_FK_Keywords
foreign key (KeywordID)
references Keywords (KeywordID));
步骤3:使用一个简单的组来查询生成“云”(以示例以“云”为含义最常见的100个标签):
with cte as (
SELECT TOP 100 KeywordID, count(*) as Count
FROM CompanyKeywords
group by KeywordID
order by count(*) desc)
select k.Keyword, c.Count
from cte c
join Keyword k on c.KeywordID = k.KeywordID;
步骤4:缓存结果很少发生变化,并且耗时。
其他提示
我宁愿看到您的设计归一化 由Remus建议, ,但是如果您无法改变设计...
您可以使用解析功能(我将使用的示例是从中获取的 这里),解析您的关键字并计算它们。
CREATE FUNCTION [dbo].[fnParseStringTSQL] (@string NVARCHAR(MAX),@separator NCHAR(1))
RETURNS @parsedString TABLE (string NVARCHAR(MAX))
AS
BEGIN
DECLARE @position int
SET @position = 1
SET @string = @string + @separator
WHILE charindex(@separator,@string,@position) <> 0
BEGIN
INSERT into @parsedString
SELECT substring(@string, @position, charindex(@separator,@string,@position) - @position)
SET @position = charindex(@separator,@string,@position) + 1
END
RETURN
END
go
create table MyTest (
id int identity,
keywords nvarchar(256)
)
insert into MyTest
(keywords)
select 'sql server,oracle,db2'
union
select 'sql server,oracle'
union
select 'sql server'
select k.string, COUNT(*) as count
from MyTest mt
cross apply dbo.fnParseStringTSQL(mt.keywords,',') k
group by k.string
order by count desc
drop function dbo.fnParseStringTSQL
drop table MyTest
雷木斯(Remus)和乔(Joe)都是正确的,但是是的,就像乔所说的话,如果您没有选择,那么您必须忍受它。我想我可以使用XML数据类型为您提供简单的解决方案。您已经可以通过执行此查询轻松查看解析列
WITH myCommonTblExp AS (
SELECT CompanyID,
CAST('<I>' + REPLACE(Keywords, ',', '</I><I>') + '</I>' AS XML) AS Keywords
FROM Companies
)
SELECT CompanyID, RTRIM(LTRIM(ExtractedCompanyCode.X.value('.', 'VARCHAR(256)'))) AS Keywords
FROM myCommonTblExp
CROSS APPLY Keywords.nodes('//I') ExtractedCompanyCode(X)
现在知道您可以做到这一点,您要做的就是对它们进行分组和计数,但是您不能对XML方法进行分组,因此我的建议是创建上面查询的视图
CREATE VIEW [dbo].[DissectedKeywords]
AS
WITH myCommonTblExp AS (
SELECT
CAST('<I>' + REPLACE(Keywords, ',', '</I><I>') + '</I>' AS XML) AS Keywords
FROM Companies
)
SELECT RTRIM(LTRIM(ExtractedCompanyCode.X.value('.', 'VARCHAR(256)'))) AS Keywords
FROM myCommonTblExp
CROSS APPLY Keywords.nodes('//I') ExtractedCompanyCode(X)
GO
并在该观点上执行您的统计
SELECT Keywords, COUNT(*) AS KeyWordCount FROM DissectedKeywords
GROUP BY Keywords
ORDER BY Keywords
无论如何,这是全文 - >http://anyrest.wordpress.com/2010/08/13/converting-parsing-delimited-string-column-in-sql-sql-to-rows/
不隶属于 StackOverflow