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.

¿Fue útil?

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

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

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/

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top