タグクラウドアルゴリズムの提案
-
28-09-2019 - |
質問
私はMSSQL 2005テーブルを持っています:
[Companies](
[CompanyID] [int] IDENTITY(1,1) NOT NULL,
[Title] [nvarchar](128),
[Description] [nvarchar](256),
[Keywords] [nvarchar](256)
)
この会社のタグクラウドを生成したいです。しかし、私はすべてのキーワードをコンマで区切った1つの列に保存しました。ほとんどの使用されているキーワードによってタグクラウドを生成する方法に関する提案。会社ごとに数百万の企業が約10のキーワードを獲得する可能性があります。
ありがとうございました。
解決
ステップ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:結果をキャッシュすることはめったになく、高価に計算されます。
他のヒント
私はむしろあなたのデザインが正常化されているのを見たいです レムスによって提案されています, 、しかし、あなたがあなたのデザインを変えることができない時点にいるなら...
あなたは解析機能を使用できます(私が使用する例はから取得されます ここ)、キーワードを解析してカウントします。
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
レムスとジョーの両方は正しいですが、あなたが選択肢がなければジョーが言ったことはそうです、そしてあなたはそれと一緒に暮らす必要があります。 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-to-lows/