Помогите с рекурсивным запросом - PullRequest
1 голос
/ 27 декабря 2008

У меня следующая проблема, которую я не смог успешно решить. Ваша помощь будет оценена. Я использую SQL 2005 и пытаюсь сделать это с помощью CTE.

Таблица имеет следующие 2 столбца

DocNum    DocEntry
1              234
2              324
2              746
3              876
3              764
4              100
4              387

Ожидаемый результат выглядит следующим образом

1                 234
2                 324, 746
3                 876, 764
4                 100, 387

Спасибо Рахул Джайн


Дальнейшее объяснение расшифровано из комментариев:

Я использую запрос, подобный следующему:

WITH ABC (DocNum, DocEntry) AS
   (SELECT DocNum, Cast(DocEntry As VARCHAR(8000))
        FROM Temp5
        WHERE DocNum = 1
    UNION ALL
    SELECT a.DocNum, A.DocEntry + ', ' + B.DocEntry
        FROM ABC B INNER JOIN Temp5 A ON B.DocNum +1= A.DocNum
         WHERE A.DOCNUM > 1)
SELECT * FROM ABC;

Результат запроса выше выглядит следующим образом

1 234
2 234, 324
2 234, 746
3 234, 746, 876
3 234, 746, 764

Я не хочу, чтобы эти числа повторялись, как показано в вопросе.

Ответы [ 4 ]

3 голосов
/ 27 декабря 2008

Вот статья, описывающая методы для этого:

Преобразование нескольких строк в строку CSV

2 голосов
/ 27 декабря 2008

Я не думаю, что CTE - это полный ответ на вашу проблему. Вам нужен запрос PIVOT, в котором число столбцов в PIVOT неизвестно во время запроса. Этот вопрос и ответ выглядят так, как вы хотите:

PIVOT в sql 2005

PIVOT в sql 2005

Из примера, приведенного в ответе выше, это модифицированный SQL для вашей таблицы (которую я назвал q395075 - так что вам просто нужно заменить ее именем таблицы):

DECLARE @sql AS varchar(max)
DECLARE @pivot_list AS varchar(max) -- Leave NULL for COALESCE technique
DECLARE @select_list AS varchar(max) -- Leave NULL for COALESCE technique

SELECT @pivot_list = COALESCE(@pivot_list + ', ', '') + '[' + CONVERT(varchar, PIVOT_CODE) + ']'
        ,@select_list = COALESCE(@select_list + ', ', '') + '[' + CONVERT(varchar, PIVOT_CODE) + '] AS [col_' + CONVERT(varchar, PIVOT_CODE) + ']'
FROM (
    SELECT DISTINCT PIVOT_CODE
    FROM (
        SELECT DocNum, DocEntry, ROW_NUMBER() OVER (PARTITION BY DocNum ORDER BY DocEntry) AS PIVOT_CODE
        FROM q395075
    ) AS rows
) AS PIVOT_CODES

SET @sql = '
;WITH p AS (
    SELECT DocNum, DocEntry, ROW_NUMBER() OVER (PARTITION BY DocNum ORDER BY DocEntry) AS PIVOT_CODE
    FROM q395075
)
SELECT DocNum, ' + @select_list + '
FROM p
PIVOT (
    MIN(DocEntry)
    FOR PIVOT_CODE IN (
        ' + @pivot_list + '
    )
) AS pvt
'

PRINT @sql

EXEC (@sql)
1 голос
/ 29 декабря 2008
SELECT 
    DocNum,
    STUFF((SELECT ', ' + CAST(DocEntry AS VARCHAR(MAX)) AS [text()]
        FROM Temp5 b
        WHERE a.DocNum = b.DocNum
        FOR XML PATH('')), 1, 2, '') AS DocEntry
FROM Temp5 a
GROUP BY DocNum

Ицик Бен-Ган в своей превосходной книге T-SQL QUERYING предлагает несколько специализированных решений для агрегирования конкатенации строк. Запрос кричит сам за себя.

0 голосов
/ 15 июня 2016
create table #a(DocNum int,  DocEntry int)

insert into #a
select 1,234 union all
select 2,324 union all
select 2,746 union all
select 3,876 union all
select 3,764 union all
select 4,100 union all
select 4,387 


select
    DocNum,
    stuff((
        select ',' + convert(varchar(25),t.DocEntry)
        from #a t
        where t.DocNum = t1.DocNum
        order by t.DocEntry
        for xml path('')
    ),1,1,'') as name_csv
from #a t1
group by DocNum
; 

выход

DocNum name_sv

   1    234    
   2    324,746    
   3    764,876    
   4    100,387   
...