逗号分隔的SQL Server结果集'JOINED'与其他列

时间:2012-08-29 13:38:53

标签: sql sql-server sql-server-2008 sql-server-2008-r2

我有一张表ProjectMaster

  Id       ProjectName
  1         A
  2         B
  3         C

另一张表ProjectMeter

 Id   ProjectId   MeterNumber
 1      1          #0001
 2      1          #0002
 3      1          #0003 
 4      2          #0004
 5      2          #0005 
 6      3          #0006

我希望有以下输出

ProjectName   MeterNumbers 
 A             #0001, #0002, #0003
 B             #0004, #0005
 C             #0006

我尝试了thisthis,但无法解决我的问题。 我不能使用表变量。

我有一个已编写的存储过程,它带来了许多joined表的数据。 ProjectMaster也恰好在其中一个表中加入。现在我需要从ProjectMeter中获取数据,这样,每一行都连接了与该列中的ProjectId相对应的ProjectMeter.MeterNumber。

现在,我得到了所有行中所有排队的连续列表。

I cannot use CURSOR, TABLE variable , Temp TABLE 

(我希望我的事业还能做些什么)

请帮助.....

3 个答案:

答案 0 :(得分:4)

试试这个:

SELECT projectname, STUFF((SELECT distinct ', ' + meternumber 
              from projectmeter m
              where p.id = m.projectid
            FOR XML PATH(''), TYPE

            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'') MeterNumbers
from projectmaster p

请参阅SQL Fiddle with Demo

答案 1 :(得分:1)

DECLARE @ProjectMaster AS TABLE
    (
      ID INT IDENTITY(1, 1) ,
      ProjectName VARCHAR(2)
    )
DECLARE @ProjectMeter AS TABLE
    (
      ID INT IDENTITY(1, 1) ,
      ProjectID INT ,
      MeterNumber VARCHAR(50)
    )

INSERT  INTO @ProjectMaster
        ( ProjectName )
VALUES  ( 'A' )

INSERT  INTO @ProjectMeter
        ( ProjectID, MeterNumber )
VALUES  ( 1, '#0001' )
INSERT  INTO @ProjectMeter
        ( ProjectID, MeterNumber )
VALUES  ( 1, '#0002' )

SELECT pMaster.ID, STUFF(( SELECT  ',' + MeterNumber
                FROM    @ProjectMeter
              FOR
                XML PATH('')
              ), 1, 1, '') AS 'Concat Result'
FROM    @ProjectMeter pMeter
        INNER JOIN @ProjectMaster pMaster ON pMaster.ID = pMeter.ProjectID
GROUP BY pMaster.ID

我在这里使用了表变量,但你肯定只需删除@' s,因为我使用了与你指定的相同的表名?不确定这是否可以? :)

答案 2 :(得分:1)

同样在MS SQL中,您可以使用recursive query with CTE

这是SQLFiddle demo

;with t1 as (
 select t.*,
        cast(meternumber as varchar(max)) as m2,
        0 as level
     from ProjectMeter t 
     where not exists 
        (select id 
                from ProjectMeter l 
          where l.id<t.id and l.ProjectId=t.ProjectID 
        )
 union all
 select b.*,
        cast(c.m2+','+b.MeterNumber as varchar(max)) as m2,
        c.level+1 as level
     from ProjectMeter b
         inner join t1 c
             on (c.id < b.id) and (b.ProjectID=c.ProjectId)

)

select pm.ProjectName as ProjectName, 
       t1.m2 as MeterNumbers 
      from t1 
      inner join
        (select ProjectId,max(level) ml 
              from t1 
          group by ProjectId
        ) t2  
            on (t1.ProjectId=t2.ProjectID) and (t1.level=t2.ml)
       left join ProjectMaster pm 
           on (t1.ProjectId=pm.Id)
order by t1.ProjectID