powered by simpleCommunicator - 2.0.40     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Агрегирование полей char ?
12 сообщений из 12, страница 1 из 1
Агрегирование полей char ?
    #32002317
Vilarik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет! Один маленький вопрос?

Есть таблица table1
id name
=========
1 aaa
1 bbb
2 ccc
3 ddd
2 eee

надо получить
id name
=============
1 aaa, bbb
2 ccc, eee
3 ddd

Как?

Может так? Но не нашел что подставить вместо 'ххх' :о)

select id, xxx(name + ', ')
from table1
group by id

Алексей
...
Рейтинг: 0 / 0
Агрегирование полей char ?
    #32002320
Фотография Garya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Select Id, Min(Name), Max(Name) from Table1 Group by ID
...
Рейтинг: 0 / 0
Агрегирование полей char ?
    #32002321
Фотография Garya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извини, поторопился. Приведенный выше запрос вернет следующее:
=============
1 aaa bbb
2 ccc eee
3 ddd ddd <- повторение одного значения
Теперь на основании полученных данных можно сравнить второе поле с третьим и если они одинаковые, в третьем поле вывести Null (или пустую строку - чтоб больше нравится).
...
Рейтинг: 0 / 0
Агрегирование полей char ?
    #32002326
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Единственно что можно - загнать общую строку в переменную.

declare @s varchar(111)
select @s=''
select @s=@s+','+name
from table1
select substring(@s,2,111)
...
Рейтинг: 0 / 0
Агрегирование полей char ?
    #32002339
Vilarik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо Garya,

вариант
"Select Id, Min(Name), Max(Name) from Table1 Group by ID"
выход из положения, но частичный. Так как, количество записей с одним ID можетбыть больше 2х.

А вот предложение SergSuper я не понял до конца. :о( Не мог бы ты развить свою мысль.

declare @s varchar(111)
select @s=''
select @s=@s+','+name
from table1
select substring(@s,2,111)

Из этого кода я понимаю, что мы просто соберем в одну строку все значения поля Name, тоесть результат будет:
=======================
aaa, bbb, ccc, ddd, eee

Алексей
...
Рейтинг: 0 / 0
Агрегирование полей char ?
    #32002342
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Развиваю мысль до конца:
запросы типа
select id, xxx(name + ', ')
from table1
group by id

никак не сделать
можно перебирать в цикле id, но без цикла - никак.
Естественно это при условии что мы не знаем сколько у нас будет значений по каждому id. Если у нас есть ограниченное (небольшое) их количество, то можно примерно так:
create table #t(id int, c varchar(10))
insert #t select 1, 'aaa'
insert #t select 1, 'bbb'
insert #t select 2, 'ccc'
insert #t select 3, 'ddd'
insert #t select 2, 'eee'
insert #t select 2, 'kkk'

select t1. id, t1.c, t2.c, t3.c,t1.c+ coalesce(t2.c,'')+ coalesce(t3.c,'')
from #t t1
left outer join #t t2 on t1.id=t2.id and t1.c>t2.c
left outer join #t t3 on t1.id=t3.id and t2.c>t3.c

Т.е. когда значений не больше 3-х

Тут еще надо подумать как лишние записи убрать, у меня просто времени сейчас нет
...
Рейтинг: 0 / 0
Агрегирование полей char ?
    #32002380
dmitry
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По-моему, это тот случай, когда придется таки использовать курсоры....
...
Рейтинг: 0 / 0
Агрегирование полей char ?
    #32002382
vitaly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А если воспользоваться UNION
надо только знать количество полей

делаем select во временную таблицу с union

затем делаем группировку

если надо напишу пример
...
Рейтинг: 0 / 0
Агрегирование полей char ?
    #32002383
vitaly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А если воспользоваться UNION
надо только знать количество полей

делаем select во временную таблицу с union

затем делаем группировку

если надо напишу пример
...
Рейтинг: 0 / 0
Агрегирование полей char ?
    #32002388
VILARik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем спасибо,
В данном случае, как вариант, устроил вывод двух значений Min and Max. Добавил Case и вывожу
так - когда:
1 значение name = а
2 значения name = а, б
3 занчения name = а...с

Но на самом деле если связываешь две таблицы один ко многим и ожидается небольшое количество значений (предположим от 1 до 5) то удобно выводить в списке как одно значение, через запятую. Вот в SQL2000 появилось такое понятие как пользовательские функции (разновидность сохраненной процедуры, которую можно вызывать в SELECTE), синтаксис типа "select id, name=GetName(id)". Только наверное это будет сильно тормозить :о(

Алексей
...
Рейтинг: 0 / 0
Агрегирование полей char ?
    #32002395
Фотография Garya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если заранее известно максимальное количество значений с одинаковым ID, можно сделать запрос на максимальное количество колонок. Что-то в этом роде (здесь приводится на 4 колонки - модифицируй под свои потребности):
SELECT M1.ID, MIN(M1.Name), MIN(M2.Name), MIN(M3.Name), MIN(M4.Name)
FROM MyTable M1 LEFT OUTER JOIN
MyTable M2 ON M1.ID = M2.ID AND M1.Name < M2.Name LEFT OUTER JOIN
MyTable M3 ON M2.ID = M3.ID AND M2.Name < M3.Name LEFT OUTER JOIN
MyTable M4 ON M3.ID = M4.ID AND M3.Name < M4.Name
GROUP BY M1.ID
...
Рейтинг: 0 / 0
Агрегирование полей char ?
    #32002410
Denis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет всем!

Очень понравилась задачка, люблю такие


Видимо в теории, в общем случае, эта задачка решается только применением курсора (лично я против курсоров) или цикла!

Если бы можно было выполнять UPDATE .. ORDER BY или получать во время выполнения UPDATE досуп к уже модифициоравнным этим оператором данным, тогда все было бы просто!
Тем не менее мне удалось добиться требуемого результата, но не совсем корректным способом, хотя кто-то может посчитает его совсем некорректным
итак ==>

--drop table #t -- это если лень будет набирать drop table при повторном выполнении
--drop table #t_grp

create table #t(id int, c varchar(10))
insert #t select 1, 'aaa'
insert #t select 1, 'bbb'
insert #t select 2, 'acc'
insert #t select 3, 'add'
insert #t select 2, 'aee'
insert #t select 2, 'akk'
insert #t select 1, 'aaz'
insert #t select 1, 'bbz'
insert #t select 2, 'ccz'
insert #t select 3, 'ddz'
insert #t select 2, 'eez'
insert #t select 2, 'kkz'

select id, c, cast('' as varchar(111)) sum_c into #t_grp from #t
create index t_grp_ind2 on #t_grp(id)

declare @str varchar(111), @i int, @i_old int
select @str = ''
select @i = min(id) - 1 from #t
update a
set @i_old = @i,
@i = a.id,
@str = a.sum_c = ltrim(case when @i_old <> @i then ''
else @str + ', ' end + a.c)
from #t_grp a with (index = t_grp_ind2)

select * from #t
select * from #t_grp order by id
select id, max(sum_c) from #t_grp group by id order by id

<==

Узость данного решения IMHO именно в попытке заставить UPDATE идти по конкретному индексу, я не уверен что результат котрый я получил на сервере версии 7.00.961, так же успешно будет повторен и на других версиях сервера, или даже просто на другом железе

Очень хотелось бы, по этому поводу, услышать мнение хорошо теоритически подкованных людей (с легкостью владеющих базой знаний Microsoft'а )

Заранее спасибо всем откликнувшимся


Denis

P.S. Естественно можно просто написать триггер на INSERT, UPDATE, DELETE в котором использовать цикл - тоже очень симпатичное решение... IMHO
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Агрегирование полей char ?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]