实施CTE

时间:2011-07-15 20:30:17

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

我有下表:

create table #prd
(
  ver varchar(20),
  fam varchar(20),
  mm varchar(20),
)

insert into #prd values('dt','fam1','111')
insert into #prd values('dt','fam1','222')
insert into #prd values('mb','fam1','333')
insert into #prd values('mb','fam2','444')

我需要使用CTE输出如下:

ver       family       MM
-------   ---------    ----------    
DT          fam1         111,222  
mb          fam1         333  
mb          fam2         444

请帮助!!

3 个答案:

答案 0 :(得分:5)

您不需要CTE。这是一个不使用CTE的解决方案

SELECT ver, fam,
    STUFF((
      SELECT  ', ' + mm
      FROM #prd AS prd
      WHERE p.ver = prd.ver
        AND p.fam = prd.fam
      ORDER BY mm
      FOR XML PATH('')
    ), 1, 2, '') AS MM
FROM #prd AS p
GROUP BY ver, fam

如果你需要它作为CTE,试试这个

;WITH prd_CTE AS
    (
    SELECT ver, fam,
        STUFF((
          SELECT  ', ' + mm
          FROM #prd AS prd
          WHERE p.ver = prd.ver
            AND p.fam = prd.fam
          ORDER BY mm
          FOR XML PATH('')
        ), 1, 2, '') AS MM
    FROM #prd AS p
    GROUP BY ver, fam
    )
SELECT *
FROM prd_CTE

答案 1 :(得分:3)

不使用for xml path('')

的CTE版本
;with cte1 as
(
  select *,
         row_number() over(partition by ver, fam order by mm) as rn
  from #prd       
),
cte2 as
(
  select ver,
         fam,
         cast(mm as varchar(max)) as mm,
         rn
  from cte1
  where rn = 1
  union all
  select c1.ver,
         c1.fam,
         c2.mm+','+c1.mm,
         c1.rn
  from cte1 as c1
    inner join cte2 as c2
      on c1.rn = c2.rn + 1 and
         c1.ver = c2.ver and
         c1.fam = c2.fam
),
cte3 as
(
  select ver,
         fam,
         mm,
         row_number() over(partition by ver, fam order by rn desc) as rn 
  from cte2
)
select ver,
       fam,
       mm
from cte3
where rn = 1

答案 2 :(得分:0)

您可以使用用户定义的函数,该函数将“ver”作为参数并返回MM逗号分隔或您可以使用数据