Группировать строки при объединении определенного столбца с разделителем - PullRequest
2 голосов
/ 16 июня 2009

Мне нужно как-то сгруппировать строки при конкатенации определенного столбца, я не уверен, как бы я поступил так. Ниже приведен пример того, что мне нужно.

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

Я не уверен, возможно ли это, но было бы очень полезно, если бы кто-нибудь знал, как это сделать. Заранее спасибо.

Ответы [ 5 ]

2 голосов
/ 17 июня 2009

ВЫБЕРИТЕ p1.personage, (ВЫБЕРИТЕ personName + ',' ОТ людей р2 ГДЕ p2.personage = p1.personage ЗАКАЗАТЬ от personName FOR XML PATH ('')) AS Результаты ОТ людей р1 GROUP BY персонаж;

1 голос
/ 16 июня 2009

Это сложная проблема. Для более глубокого рассмотрения этого см. Этот превосходный пост:

* ** 1003 тысячи два *http://www.simple -talk.com / SQL / T-SQL-программирование / конкатенация-строка-значения-в-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 age=@age
    fetch next from cur into @age   
end

close cur
deallocate cur

select * from #out
0 голосов
/ 08 сентября 2009

Если вы используете MySQL, это так просто, как могло бы быть

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

Есть также опции ORDER и DISTINCT:)

0 голосов
/ 16 июня 2009

Это сложная проблема в Sql Server. Вы можете, например, создать пользовательский агрегат конкатенации строк . Но для этого необходимо загрузить сборку .NET на свой сервер Sql; не все администраторы БД согласны с этим.

На стороне клиента это действительно просто. Почему бы вам не заняться решением этой клиентской стороны?

0 голосов
/ 16 июня 2009

Вот способ без курсоров, используя ссылку, которую 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 ;  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...