我有以下CTE:
;WITH combo (id, [program_name]) AS
(
SELECT
1
, CAST('' AS VARCHAR(MAX))
UNION ALL
SELECT
cte.id + 1
,(cte.[program_name] + pl.[program_name] + '; ')
FROM (
SELECT
RowNum = ROW_NUMBER() OVER (ORDER BY people_id)
--people_id
,p.[program_name]
FROM event_log_Rv E
JOIN PROgrams_view p on p.program_info_id = e.program_providing_service
where people_id = 'DFA3AFE5-F681-4B1B-89F0-31D04FA6BF7D'
) pl
JOIN combo cte ON pl.RowNum = cte.id
)
SELECT TOP 1 id, [program_name] FROM combo ORDER BY id DESC
当我运行此CTE时,我收到此错误:
Msg 530,Level 16,State 1,Line 1
声明终止。在语句完成之前,最大递归100已经用尽。
people_id
和program_providing_service
是uniqueidentifier
数据类型。
如何在列表中添加列出行号的CTE?我最终想做的是让这个CTE显示所有程序/客户端。
我试图通过在此CTE中添加行号以加入CTE和组合来实现此功能,但如果您能想到以不同的方式在一行中显示所有程序/客户端,我可以接受这一点。
例如,我想:
people_id Programs
DFA3AFE5-F681-4B1B-89F0-31D04FA6BF7D IHS; MCP; DCS
答案 0 :(得分:1)
逗号分隔列表中的一对多关系放在一个列中,它会占用很多行并将它们放在一个'(char)'分隔列表中?我使用xml类型,因为你可以拥有可能随时间变化的复杂结构。对于那种恕我直言,递归非常激烈。
这是一个自我提取的例子,下面我将解释它:
declare @Person Table ( personID int identity, person varchar(8));
insert into @Person values ('Brett'),('Sean'),('Chad'),('Michael'),('Ray'),('Erik'),('Queyn');
declare @Orders table ( OrderID int identity, PersonID int, Desciption varchar(32), Amount int);
insert into @Orders values (1, 'Shirt', 20),(1, 'Shoes', 50),(2, 'Shirt', 22),(2, 'Shoes', 52),(3, 'Shirt', 20),(3, 'Shoes', 50),(3, 'Hat', 20),(4, 'Shirt', 20),(5, 'Shirt', 20),(5, 'Pants', 30),
(6, 'Shirt', 20),(6, 'RunningShoes', 70),(7, 'Shirt', 22),(7, 'Shoes', 40),(7, 'Coat', 80)
Select top 100
p.person
, o.Desciption
from @Person p
join @Orders o on p.personID = o.PersonID
order by p.person
Select
p.person
, replace(
replace(
replace(
(
select
o.Desciption as d
from @Orders o
where o.PersonID = p.personID
for xml auto
), '"/><o d="', ', ')
, '<o d="', '')
, '"/>', '') as SeperatedList
from @Person p
order by p.person
这种方法效果很好,因为它将子分组放在它自己的数据集中,而且我所看到的通常比粘贴到现有字符串的字符串操作快得多,因为你必须使用这种方法,一旦加上内存,一次加内存加内存,一次加内存加内存....你明白了。此方法立即获取数据集的所有内容,然后仅将结果评估给最终用户。如果您有数百万个子行且速度很慢,我会先考虑转储到CTE,表变量或临时表,然后再将它们作为XML列进行转换。