1

我有以下 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_serviceuniqueidentifier

如何在此 CTE 中添加列以列出行号?我最终想要做的是让这个 CTE 显示所有程序/客户端。

我试图通过在此 CTE 中添加行号来加入 CTE 和组合来使其工作,但如果您能想到一种不同的方式来仅在一行中显示所有程序/客户端,我可以接受这一点。

例如,我想要:

people_id                               Programs
DFA3AFE5-F681-4B1B-89F0-31D04FA6BF7D    IHS; MCP; DCS
4

1 回答 1

1

一对多关系的逗号分隔列表放入单个列中,其中占用多行并将它们放入“(字符)”分隔列表中?我为此使用 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
  1. 我正在做一个嵌套选择以获取父对象(在我的示例中为人)的所有子元素(在我的示例中为订单)。
  2. 您不能将 TSQL 中的数组作为列返回......除非它存储为 xml,它可以是它自己的多元素树结构作为单列。
  3. 从本质上讲,“for xml auto”会给我返回文本而不是 xml 类型(有点酷)。我遗漏了很多内容,并且有一整部分的白皮书仅介绍了使用“FOR XML (something)”。Auto 假定元素名称是我的别名 'o' 并且我的列被命名为 'd' 这成为一个属性。
    1. 由于默认情况下转换为文本,我不必担心转换问题,因为我需要做一些查找和替换
    2. 我基本上找到了我为元素和列应用的标签,并用列分隔符“替换()”它们。我选择了',',你可以使用任何你想要的。
    3. 我用另外两个替换结束和开始元素。瞧,您现在有一个 '(char)' 分隔列表。

这种方法效果很好,因为它将子分组在它自己的数据集中分开,并且从我所看到的情况来看,与粘贴到现有字符串的字符串操作相比通常非常快,因为您必须执行该方法,一次加内存,一次加内存加内存,一次加内存加内存....你明白了。此方法一次获取数据集的所有内容,然后仅评估对最终用户的演示。如果您有数百万个子行并且速度很慢,我会考虑先转储到 CTE、表变量或临时表,然后可能先将它们转换为 XML 列。

于 2013-07-17T21:48:35.030 回答