Sugerencia para un algoritmo de nube de etiquetas
-
28-09-2019 - |
Pregunta
Tengo una tabla de MSSQL 2005:
[Companies](
[CompanyID] [int] IDENTITY(1,1) NOT NULL,
[Title] [nvarchar](128),
[Description] [nvarchar](256),
[Keywords] [nvarchar](256)
)
Quiero generar una nube de etiquetas para estas empresas. Pero he salvado todas las palabras clave en una columna separadas por comas. Alguna sugerencia sobre cómo generar nube de etiquetas por la mayoría de las palabras clave utilizadas. Podría haber millones de empresas aproximadamente diez palabras clave por empresa.
Gracias.
Solución
Paso 1: separar las palabras clave en una relación adecuada (tabla).
CREATE TABLE Keywords (KeywordID int IDENTITY(1,1) NOT NULL
, Keyword NVARCHAR(256)
, constraint KeywordsPK primary key (KeywordID)
, constraint KeywordsUnique unique (Keyword));
Paso 2: Asignar los muchos-a-muchos relación entre las empresas y las etiquetas en una tabla separada, al igual que todas las relaciones muchos-a-muchos:
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));
Paso 3: utilizar un grupo simple consulta para generar el 'nube' (por ejemplo tomando la 'nube' en el sentido de las 100 etiquetas más comunes):
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;
Paso 4:. Caché el resultado a medida que cambia rara vez y se calcula costosamente
Otros consejos
Prefiero ver tu diseño normalice lo sugerido por Remus , pero si usted está en un punto donde no se puede cambiar el diseño de su ...
Se puede utilizar una función de análisis (el ejemplo voy a utilizar se toma de aquí ), para analizar las palabras clave y contarlos.
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
Tanto Remus y Joe son correctas, pero sí como lo que Joe dijo que si usted no tiene una elección, entonces usted tiene que vivir con ella. Creo que te puedo ofrecer una solución fácil mediante el uso de un tipo de datos XML. Ya se puede ver fácilmente la columna analizado por hacer esta consulta ??p>
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)
Ahora sabiendo que se puede hacer eso, todo lo que tiene que hacer es agruparlos y el recuento, pero no se puede métodos XML de grupo así que mi sugerencia es crear una vista de la consulta anterior
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
y realizar el recuento en ese punto de vista ??p>
SELECT Keywords, COUNT(*) AS KeyWordCount FROM DissectedKeywords
GROUP BY Keywords
ORDER BY Keywords
De todas formas aquí está el artículo completo -> http://anyrest.wordpress.com/2010/08/13/converting-parsing-delimited-string-column-in-sql-to-rows/