Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Хитрая группировка  [new]
stenford
Member

Откуда: урал
Сообщений: 2850
Есть такая таблица:

declare @t as table(id int, number int, descr varchar(50), id_rank int)
insert into @t values(1, 6, 'hello1', 1)
insert into @t values(2, 4, 'hello2', 1)
insert into @t values(3, 7, 'hello3', 2)
insert into @t values(4, 6, 'hello4', 1)
insert into @t values(5, 1, 'hello5', 2)
insert into @t values(6, 9, 'hello6', 3)


В ней id_rank означает признак дубликата, и записи с id_rank > 1 должны схлопнуться в одну с таким условием, что-бы поле number выбралось максимальное значение, а поле desсr сложилось, т.е. результат должен быть таким:

1   6   'hello1'
2   7   'hello2hello3'
4   9   'hello4hello5hello6'


можно-ли так сделать?
22 май 13, 14:54    [14333355]     Ответить | Цитировать Сообщить модератору
 Re: Хитрая группировка  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
Поиск
22 май 13, 14:56    [14333378]     Ответить | Цитировать Сообщить модератору
 Re: Хитрая группировка  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
declare @t as table(id int, number int, descr varchar(50), id_rank int)
insert into @t values(1, 6, 'hello1', 1)
insert into @t values(2, 4, 'hello2', 1)
insert into @t values(3, 7, 'hello3', 2)
insert into @t values(4, 6, 'hello4', 1)
insert into @t values(5, 1, 'hello5', 2)
insert into @t values(6, 9, 'hello6', 3)

SELECT id=MIN(T.id),number=MAX(T.number),
(
 SELECT TT.descr
 FROM @t TT
 WHERE TT.id-TT.id_rank=T.id-T.id_rank
 ORDER BY TT.id_rank
 FOR XML PATH(''),TYPE
).value('.','VARCHAR(1000)')
FROM @t T
GROUP BY T.id-T.id_rank
ORDER BY id;
22 май 13, 15:05    [14333434]     Ответить | Цитировать Сообщить модератору
 Re: Хитрая группировка  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Не понял только, что хитрого в группировке-то?


Если id не монотонно возрастает, то заменить его на ROW_NUMBER()OVER(ORDE BY id)
22 май 13, 15:07    [14333463]     Ответить | Цитировать Сообщить модератору
 Re: Хитрая группировка  [new]
stenford
Member

Откуда: урал
Сообщений: 2850
thanks!
22 май 13, 15:33    [14333728]     Ответить | Цитировать Сообщить модератору
 Re: Хитрая группировка  [new]
stenford
Member

Откуда: урал
Сообщений: 2850
в общем работает, но медленно, всего около 200К записей, и этот способ склеивает строки со скоростью около 100 строк в 5 секунд, весь файл будет обрабатываеться несколько часов. Есть-ли способ убыстрить?
23 май 13, 08:12    [14336529]     Ответить | Цитировать Сообщить модератору
 Re: Хитрая группировка  [new]
user89
Member

Откуда:
Сообщений: 2083
stenford,

???
if object_id('tempdb..#tmp') is not null drop table #tmp

declare @t as table(id int, number int, descr varchar(50), id_rank int)
insert into @t values(1, 6, 'hello1', 1) insert into @t values(2, 4, 'hello2', 1)
insert into @t values(3, 7, 'hello3', 2) insert into @t values(4, 6, 'hello4', 1)
insert into @t values(5, 1, 'hello5', 2) insert into @t values(6, 9, 'hello6', 3)

select *, id - id_rank [GrNum]
into #tmp
from @t

create clustered index ix_tmp on #tmp(GrNum)

select min(t1.id) [id], max(t1.number) [number],
(select t2.descr from #tmp t2 where t2.GrNum = t1.GrNum order by t2.id_rank for xml path(''),type).value('.','varchar(max)')
from #tmp t1
group by t1.GrNum
order by id;

if object_id('tempdb..#tmp') is not null drop table #tmp
23 май 13, 08:49    [14336614]     Ответить | Цитировать Сообщить модератору
 Re: Хитрая группировка  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1887
declare @t as table(id int, number int, descr varchar(50), id_rank int)
insert into @t values(1, 6, 'hello1', 1)
insert into @t values(2, 4, 'hello2', 1)
insert into @t values(3, 7, 'hello3', 2)
insert into @t values(4, 6, 'hello4', 1)
insert into @t values(5, 1, 'hello5', 2)
insert into @t values(6, 9, 'hello6', 3)


;with Buff( id0, id, number,descr, id_rank,step) AS(
select id as id0, id, number, cast(descr as varchar(max)), id_rank, 1 as step from @t where id_rank=1
union all
select 
  b.id0 as id0
, t.id  as id
, case when t.number > b.number then t.number else b.number end as number
, b.descr+t.descr as descr
, t.id_rank 
, b.step+1 as step
from Buff b
join @t t on t.id = b.id+1 and t.id_rank>1
)
select top 1 with ties id0 as id, number,descr from Buff
order by ROW_NUMBER()OVER(PARTITION BY id0 ORDER BY step desc)
23 май 13, 09:09    [14336713]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить