2009-06-16 13 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

+0

私はカーソルが好きではありません...しかし、これを行う別の方法はありますか? – tekBlues

0

は、使用して、カーソルのない方法です。テックブルースが投稿に投稿したリンク:

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を作成できます。しかし、それはあなたのSQL Serverに.NETアセンブリをロードする必要があります。すべてのDBAがそれに同意するわけではありません。

クライアント側では、これは簡単です。なぜあなたはこのクライアント側を解決するために見ていないのですか?

2

SELECT p1.personage、 (SELECT人がP2からPERSONNAME + '' p2.personage = p1.personage XMLパスのPERSONNAME ( '')BY ORDERが )人々が をP1からAS 結果GROUP BY人物;

0

MySQLを使用している場合、それはそれは

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

かもしれないのと同じくらい簡単ですORDERとDISTINCTオプションもあります:)

関連する問題