2010-09-03 77 views
3

我正在尝试使用'For Xml路径'T-SQL从列中生成一个以逗号分隔的值列表。这似乎工作得很好,但问题是我想获得在逗号分隔列表中的项目的计数。这里是我用来生成逗号的代码示例分隔列表:Sql For Xml路径获取节点数

Create Table #List ([col] varchar) 

Insert Into #List Select '1'; 
Insert Into #List Select '2'; 
Insert Into #List Select '3' 

Select ',' + [col] From #List For Xml Path('') 

这使结果1,2,3不如预期,但没有办法让计,有3个项目。任何添加计数的尝试都会将它添加到xml中。我结合这个代码的CTE得到计数:

With CTE As (
    Select 
     [col] 
    From 
     #List 
) 
Select 
    (Select ',' + [col] From #List For Xml Path('')) As [List], 
    Count(*) As [Count] 
From 
    CTE 

有没有更简单/清洁的方式来获得节点的计数,不使用CTE?有人指出,你可以在内部select和outside之外复制from子句,但这需要保持from子句同步。我想获得列表和计数,但只有一次写入from子句。

回答

2

如何从CTE而不是临时表绘图数据?

With CTE As (
    Select 
     [col] 
    From 
     #List 
    -- Many joins 
    -- Complicated where clause 
) 
Select 
    (Select ',' + [col] From Cte For Xml Path('')) As [List], 
    Count(*) As [Count] 
From 
    CTE 

这将允许你保持你的连接和搜索谓词在一个地方。

+0

这实际上是我最终使用的。但是,我最终不得不在使用CTE之前将复杂的选择放入临时表中。当我直接加入CTE时,表现非常糟糕。 CTE中的查询返回大约需要2秒,但是,它会将整个查询与逗号列表累积小时数结合起来。花了这么长时间,我从来没有让它完成。如果我首先将复杂选择放入临时表中,则查询需要一秒钟才能运行。我唯一能想到的是,CTE中的选择正在为每次迭代重新运行? – user355930 2010-09-08 16:41:26

1

你不需要的CTE可以使用子查询的方式直接

SELECT 
     COUNT(*) AS [Count], 
     (SELECT ',' + [col] FROM #List FOR XML PATH('')) AS [List] 
FROM #List 
+0

这是一个可以接受的解决方案,但问题是它需要将from逻辑重复两次。如果我从一个有10个连接的语句中抽出,我将不得不重复在子语句和from子句中的连接。我希望能够编写一次连接逻辑并获取逗号列表和计数。我会修改我的问题。我试图给你投票,但我没有足够的代表。 – user355930 2010-09-03 19:04:03