2009-06-16 54 views
2

我不得不以某种方式在连接某个列的同时分组行,我不知道如何去做这件事。以下是我需要的一个例子。将某一列与一个分隔列连接在一起组合起来的行

CREATE TABLE People(
PersonName varchar(100), 
PersonAge int 
) 

INSERT INTO People 
SELECT 'bill', 21 

INSERT INTO People 
SELECT 'harry', 21 

INSERT INTO People 
SELECT 'wesley', 21 

INSERT INTO People 
SELECT 'tom', 42 

INSERT INTO People 
SELECT 'paul', 42 

INSERT INTO People 
SELECT 'phil', 53 

从该表中一个正常的选择将产生如下:

bill 21 
harry 21 
wesley 21 
tom  42 
paul 42 
phil 53 

我需要的是以下几点:

bill, harry, wesley 21 
tom,paul    42 
phil     53 

我不知道这是可能的,但它会如果有人知道如何去做,那真的很有帮助。提前致谢。

回答

1

这是一个难题。对于一个在它的深度处理看到这个优秀的帖子:

http://www.simple-talk.com/sql/t-sql-programming/concatenating-row-values-in-transact-sql/

对于一个简单的解决方案,我用了一个光标,它的工作:

create procedure 
doIt 
as 

create table #out 
(people varchar(2000) null, -- assumed max length of concatenated string 
age int) 

insert into #out(age) 
select distinct personAge from people 

declare @str varchar(2000) 
select @str = isnull(@str,'') + personname +',' from people 

declare @age int 
declare cur cursor for select age from #out 

open cur 
fetch next from cur into @age 

while @@fetch_status =0 
begin 
    set @str = '' 
    select @str = isnull(@str,'') + personname +',' from people where personage = @age 
    update #out set people = left(@str,len(@str)-1) where [email protected] 
    fetch next from cur into @age 
end 

close cur 
deallocate cur 

select * from #out 
+0

好了,我不喜欢的光标。但你给的链接真的很酷。 +1 :) – Kirtan 2009-06-16 10:11:22

0

下面是使用没有光标的方式tekBlues放在他的帖子中的链接:

WITH CTE (PersonAge, person_list, person_name, length) 
AS 
( 
SELECT PersonAge, CAST('' AS VARCHAR(8000)), CAST('' AS VARCHAR(8000)), 0 
FROM People 
GROUP BY PersonAge 
UNION ALL 
SELECT p.PersonAge, 
    CAST(person_list + CASE WHEN length = 0 THEN '' ELSE ', ' END + PersonName AS VARCHAR(8000)), 
    CAST(PersonName AS VARCHAR(8000)), length + 1 
FROM CTE c 
INNER JOIN People p ON c.PersonAge = p.PersonAge 
WHERE p.PersonName > c.person_name 
) 
SELECT PersonAge, person_list 
FROM 
( 
SELECT PersonAge, person_list, RANK() OVER (PARTITION BY PersonAge ORDER BY length DESC) 
FROM CTE 
) D (PersonAge, person_list, rank) 
WHERE rank = 1 ; 
0

这是Sql Server中的一个难题。例如,您可以创建一个custom string concatenation aggregate。但是这需要你将一个.NET程序集加载到你的Sql Server中;并不是所有的DBA都会同意这一点。

在客户端,这非常简单。你为什么不考虑解决这个客户端?

2

SELECT p1.personage, (SELECT PERSONNAME + '' FROM人P2 WHERE p2.personage = p1.personage ORDER BY PERSONNAME FOR XML PATH( ''))AS结果 从人P1 GROUP BY人物;

0

如果你使用MySQL,它是那样简单,因为它可以

SELECT GROUP_CONCAT(PersonName SEPARATOR ', ') as name, PersonAge 
FROM People GROUP BY PersonAge 

还有订单的不同的选项:)