Объединение одного столбца из нескольких строк в один столбец с разными ключевыми словами

У меня есть статья 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 .

1
nl ja de
@DadaDom, мне удалось вытащить его. Я объединил его с разделенной функцией & RUN Distinct SELECT на нем, который дал мне уникальные результаты
добавлено автор Learning, источник
У меня нет SQL-сервера под рукой, но как насчет разделения второго столбца на отдельные ключевые слова и попытки объединить их в выбранном?
добавлено автор Dominik Sandjaja, источник

3 ответы

Я думаю, вам придется сначала разбить данные на строки, прежде чем объединить их. Это позволит вам получить различные значения при использовании 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 |
4
добавлено
Цените, что это отлично работает, и мне также удалось найти решение, которое я также разместил в качестве решения, я был бы признателен за ваши комментарии по этому поводу с точки зрения производительности, и у меня могут быть тысячи или статья. Я буду отмечать ваш ответ как правильный.
добавлено автор Learning, источник

Коррелированный подзапрос должен сделать это:

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;
2
добавлено

One of the Solution is to combine result with Split function & Run SQL statement with DISTINCT on it. You can further modify this for your needs. I have test & it is working for me. Hope it helps other people.

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
0
добавлено
SqlCom.ru - Стиль жизни SQL
SqlCom.ru - Стиль жизни SQL
908 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только MS SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz). Предложения в @sql_ninja

SQL_Ninja
SQL_Ninja
340 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz)