2011-01-10 65 views
0

我有一个表CSV SqlServer中在2005年

列:名称,角色,部门

一个人可以有很多的角色。所以,当检索数据时,如果一个人有多个角色,我希望角色列处于CSV格式。

Name Role   Dept 
jose Role1,Role2 PWD 

假设除了记录的角色以外的所有其他细节都是相同的。

由于

回答

1

这个值就可以了你。

select 
    t3.Name, 
    left(t3.Roles, len(t3.Roles)-1) as Roles, 
    t3.Dept 
from 
    (select 
      t2.Name, 
      t2.Dept, 
      (select t1.[Role] + ',' 
      from Table1 as t1 
      where 
       t1.Name = t2.Name and 
       t1.Dept = t2.Dept 
      order by t1.[Role] 
      for xml path('')) as Roles 
     from Table1 as t2 
     group by t2.Name, t2.Dept) as t3 

这是从第一实施例采取的“的黑箱XML方法”从当前页 https://www.simple-talk.com/sql/t-sql-programming/concatenating-row-values-in-transact-sql/

内部查询建立角色作为XML的列表。 xml路径('')参数为空,因此您不会获得xml标记,只能使用逗号分隔列表。

外部查询仅用于删除每行末尾的逗号。

Group by t2.Name, t2.Dept确保您只会为Name + Dept的每个唯一组合获得一行。

0

可以创建用户定义的集合函数产生一个逗号分隔的值的列表,并且可以在查询中使用的任何其他集合函数(即MINMAXSUM等) 。

下面是从我的博客相关的职位:A SQL CLR user-defined aggregate - notes on creating and debugging

创建dbo.Concat功能后,您就可以执行以下查询:

SELECT 
    Name 
, Dept 
, dbo.Concat(Role) AS Roles 
FROM dbo.Table_1 
GROUP BY 
    Name 
, Dept 

我已经在生产环境中使用它了几年,其性能非常好,即使有大量的加工行。

0

一种选择是使用递归参数和游标。尝试与此查询:

DECLARE @Name varchar(50), @Role varchar(MAX), @Dept varchar(50) 

DECLARE role_cursor CURSOR FOR 
SELECT Name,min(Dept) 
FROM [dbo].[Table_1] 
group by Name 

OPEN role_cursor; 
FETCH NEXT FROM role_cursor 
INTO @Name, @Dept 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    set  @Role = '' 
    select @Role = @Role+[Role]+',' 
    FROM [dbo].[Table_1] 
    where [email protected] 

    select @Name,left(@Role,len(@Role)-1),@Dept 

    FETCH NEXT FROM role_cursor 
    INTO @Name, @Dept 
END 
CLOSE role_cursor; 
DEALLOCATE role_cursor; 

一旦你拥有它,你可以使用插入之前,选择要插入一个结果表