|
Агрегирование полей char ?
|
|||
---|---|---|---|
#18+
Привет! Один маленький вопрос? Есть таблица 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 Алексей ... |
|||
:
Нравится:
Не нравится:
|
|||
15.02.2001, 19:41 |
|
Агрегирование полей char ?
|
|||
---|---|---|---|
#18+
Select Id, Min(Name), Max(Name) from Table1 Group by ID ... |
|||
:
Нравится:
Не нравится:
|
|||
15.02.2001, 20:01 |
|
Агрегирование полей char ?
|
|||
---|---|---|---|
#18+
Извини, поторопился. Приведенный выше запрос вернет следующее: ============= 1 aaa bbb 2 ccc eee 3 ddd ddd <- повторение одного значения Теперь на основании полученных данных можно сравнить второе поле с третьим и если они одинаковые, в третьем поле вывести Null (или пустую строку - чтоб больше нравится). ... |
|||
:
Нравится:
Не нравится:
|
|||
15.02.2001, 20:08 |
|
Агрегирование полей char ?
|
|||
---|---|---|---|
#18+
Единственно что можно - загнать общую строку в переменную. declare @s varchar(111) select @s='' select @s=@s+','+name from table1 select substring(@s,2,111) ... |
|||
:
Нравится:
Не нравится:
|
|||
15.02.2001, 20:49 |
|
Агрегирование полей char ?
|
|||
---|---|---|---|
#18+
Спасибо 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 Алексей ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2001, 11:07 |
|
Агрегирование полей char ?
|
|||
---|---|---|---|
#18+
Развиваю мысль до конца: запросы типа 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-х Тут еще надо подумать как лишние записи убрать, у меня просто времени сейчас нет ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2001, 11:54 |
|
Агрегирование полей char ?
|
|||
---|---|---|---|
#18+
По-моему, это тот случай, когда придется таки использовать курсоры.... ... |
|||
:
Нравится:
Не нравится:
|
|||
19.02.2001, 16:49 |
|
Агрегирование полей char ?
|
|||
---|---|---|---|
#18+
А если воспользоваться UNION надо только знать количество полей делаем select во временную таблицу с union затем делаем группировку если надо напишу пример ... |
|||
:
Нравится:
Не нравится:
|
|||
19.02.2001, 17:03 |
|
Агрегирование полей char ?
|
|||
---|---|---|---|
#18+
А если воспользоваться UNION надо только знать количество полей делаем select во временную таблицу с union затем делаем группировку если надо напишу пример ... |
|||
:
Нравится:
Не нравится:
|
|||
19.02.2001, 17:09 |
|
Агрегирование полей char ?
|
|||
---|---|---|---|
#18+
Всем спасибо, В данном случае, как вариант, устроил вывод двух значений Min and Max. Добавил Case и вывожу так - когда: 1 значение name = а 2 значения name = а, б 3 занчения name = а...с Но на самом деле если связываешь две таблицы один ко многим и ожидается небольшое количество значений (предположим от 1 до 5) то удобно выводить в списке как одно значение, через запятую. Вот в SQL2000 появилось такое понятие как пользовательские функции (разновидность сохраненной процедуры, которую можно вызывать в SELECTE), синтаксис типа "select id, name=GetName(id)". Только наверное это будет сильно тормозить :о( Алексей ... |
|||
:
Нравится:
Не нравится:
|
|||
19.02.2001, 18:53 |
|
Агрегирование полей char ?
|
|||
---|---|---|---|
#18+
Если заранее известно максимальное количество значений с одинаковым 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 ... |
|||
:
Нравится:
Не нравится:
|
|||
19.02.2001, 20:40 |
|
Агрегирование полей char ?
|
|||
---|---|---|---|
#18+
Привет всем! Очень понравилась задачка, люблю такие Видимо в теории, в общем случае, эта задачка решается только применением курсора (лично я против курсоров) или цикла! Если бы можно было выполнять 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 ... |
|||
:
Нравится:
Не нравится:
|
|||
20.02.2001, 15:41 |
|
|
start [/forum/topic.php?fid=46&msg=32002342&tid=1827318]: |
0ms |
get settings: |
11ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
40ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
others: | 16ms |
total: | 154ms |
0 / 0 |