1

我有一篇table文章,其中有一列keywords存储标签或关键字

样本数据

Table Article
------------------------------------------
ID    keywords
------------------------------------------
1     one, two, three
2     four, five, six
3     seven, eight, three
4     one, two, three
5     twenty, hundred, one hundred one, one hundred two, seventy
6     seventy, three, two hundred 

如果我使用如下 CTE 查询,那么它会将所有关键字列连接在一行中,但另一方面也会得到重复行,这是一个问题,因为我们将有 1000 篇具有数百个相似关键字的文章。

SELECT TOP 1 
    stuff(
    (
    select cast(',' as varchar(max)) + lower(Keywords)
    from art_Article a
    for xml path('')
    ), 1, 1, '') AS All_Keywords
FROM
    art_Articles G
ORDER BY
    G.ArticleKeywords ASC;

上面的查询产生以下结果作为单行

---------------------------------------------------
All_Keywords
----------------------------------------------------
one, two, three,four, five, six,seven, eight, three,one, two, three,twenty, hundred, one hundred one, one hundred two, seventy,seventy, three, two hundred 

从结果中可以明显看出,它还显示了重复的关键字 no。时间,因为它存储在行中。他们是我只能获得一次重复关键字的方法吗?

DISTINCT如果有人可以帮助我对此进行排序以将结果作为仅包含关键字的单列,我将不胜感激。

4

3 回答 3

4

我认为您必须先将数据分成几行,然后再将它们连接在一起。这将允许您在FOR XML PATH用于获取最终列表时获得不同的值。

这是此过程的 CTE 版本:

;with cte (id, word, words) as
(
  select id,
    cast(left(keywords, charindex(',',keywords+',')-1) as varchar(50)) word,
         stuff(keywords, 1, charindex(',',keywords+','), '') words
  from article
  union all
  select id,
    cast(left(words, charindex(',',words+',')-1) as varchar(50)) word,
    stuff(words, 1, charindex(',',words+','), '') words
  from cte
  where words > ''
) 
select top 1 
    stuff((select distinct ', '+ rtrim(ltrim(word))
           from cte
           for xml path('')), 1, 1, '') AS All_Keywords
from cte

请参阅SQL Fiddle with Demo。这给出了结果:

|                                                                                                             ALL_KEYWORDS |
----------------------------------------------------------------------------------------------------------------------------
|  eight, five, four, hundred, one, one hundred one, one hundred two, seven, seventy, six, three, twenty, two, two hundred |
于 2013-01-29T10:51:58.590 回答
2

相关子查询应该这样做:

SELECT G.ID,
    stuff(
    (
    select cast(',' as varchar(max)) + lower(Keywords)
    from art_Article a
    where a.id = g.id
    for xml path('')
    ), 1, 1, '') AS All_Keywords
FROM
    art_Articles G
ORDER BY
    G.ArticleKeywords ASC;
于 2013-01-29T13:04:08.050 回答
0

解决方案之一是将结果与拆分函数结合起来,并在其上运行带有 DISTINCT 的 SQL 语句。您可以根据需要进一步修改它。我有测试,它对我有用。希望它可以帮助其他人。

DECLARE @Keywords nvarchar(MAX)
SELECT TOP 1 @Keywords =
    stuff(
    (
    select cast(',' as varchar(max)) + lower(Keywords)
    from Article U
    for xml path('')
    ), 1, 1, '') 
FROM
    Articles G
ORDER BY
    G.ArticleKeywords ASC;

SELECT DISTINCT(VALUE) AS VALUE FROM [uf_SplitKeywords] (',', @Keywords)

拆分功能代码如下

ALTER FUNCTION [dbo].[uf_SplitKeywords] 
   (  @DELIMITER VARCHAR(5), 
      @LIST      VARCHAR(MAX) 
   ) 
   RETURNS @TABLEOFVALUES TABLE 
      (  ROWID   int IDENTITY(1,1), 
         [VALUE] VARCHAR(MAX) 
      ) 
AS 
   BEGIN
   Declare @Pos int
   While LEN(@List) > 0
      begin
        Select @Pos=CHARINDEX(@Delimiter,@List,1)      
        if @Pos>0
           begin
             Insert into @TABLEOFVALUES ([Value]) Values (SubString(@List,1,@Pos -1))
             Select @LIST = STUFF(@List,1,@Pos ,'')
           end
        else  
            begin
            Insert into @TABLEOFVALUES ([Value]) Values (@List)
            Select @LIST =''
            end  
      end
   Return 
   End
于 2013-01-29T11:00:22.423 回答