Сложить в T-SQL? - PullRequest
       25

Сложить в T-SQL?

4 голосов
/ 11 ноября 2008

Если у меня есть данные в следующем формате

 id    subid      text
 1     1          Hello
 1     2          World
 1     3          !
 2     1          B
 2     2          B
 2     3          Q

И хотелось бы в этом формате:

 id  fold
 1   HelloWorld!
 2   BBQ

Как мне это сделать в T-SQL?

Ответы [ 4 ]

9 голосов
/ 11 ноября 2008

Я бы настоятельно рекомендовал против этого. Именно такие вещи должны обрабатываться на уровне приложений.

Но ... если нужно:
Объединение значений строк в Transact-SQL

2 голосов
/ 11 ноября 2008

временная таблица и курсор на ум ...

Уважаемые Downvoters: временная таблица и курсор должны быть по крайней мере такими же эффективными, как решения с рекурсивными запросами и пользовательскими функциями, принятые выше. Избавьтесь от страха перед курсорами, иногда они являются наиболее эффективным решением. Иногда они являются единственным решением. Смирись с этим.

РЕДАКТИРОВАТЬ: решение на основе курсора ниже. Обратите внимание, что он не имеет никаких ограничений для некурсорных (и более сложных) решений, предложенных в других местах, и производительность, вероятно, примерно такая же (трудно сказать из таблицы из шести строк, конечно).

и, пожалуйста, не оставляйте основную для каждого конструкцию sql только потому, что какой-то блогер говорит "это плохо"; Используй собственное суждение и здравый смысл. Я избегаю курсоров всякий раз, когда это возможно, но не до такой степени, что решение не является надежным.

--initial data table
create table #tmp (
    id int,
    subid int,
    txt varchar(256)
)

--populate with sample data from original question
insert into #tmp (id,subid,txt) values (1, 1, 'Hello')
insert into #tmp (id,subid,txt) values (1, 2, 'World')
insert into #tmp (id,subid,txt) values (1, 3, '!')
insert into #tmp (id,subid,txt) values (2, 1, 'B')
insert into #tmp (id,subid,txt) values (2, 2, 'B')
insert into #tmp (id,subid,txt) values (2, 3, 'Q')

--temp table for grouping results
create table #tmpgrp (
    id int,
    txt varchar(4000)
)

--cursor for looping through data
declare cur cursor local for
    select id, subid, txt from #tmp order by id, subid

declare @id int
declare @subid int
declare @txt varchar(256)

declare @curid int
declare @curtxt varchar(4000)


open cur

fetch next from cur into @id, @subid, @txt

set @curid = @id
set @curtxt = ''

while @@FETCH_STATUS = 0 begin
    if @curid <> @id begin
        insert into #tmpgrp (id,txt) values (@curid,@curtxt)
        set @curid = @id
        set @curtxt = ''
    end
    set @curtxt = @curtxt + isnull(@txt,'')
    fetch next from cur into @id, @subid, @txt
end

insert into #tmpgrp (id,txt) values (@curid,@curtxt)

close cur

deallocate cur

--show output
select * from #tmpgrp

--drop temp tables
drop table #tmp
drop table #tmpgrp
1 голос
/ 04 января 2011
declare  @tmp table (id int, subid int,txt varchar(256) )  
--populate with sample data from original question 
insert into @tmp (id,subid,txt) values (1, 1, 'Hello') 
insert into @tmp (id,subid,txt) values (1, 2, 'World') 
insert into @tmp (id,subid,txt) values (1, 3, '!') 
insert into @tmp (id,subid,txt) values (2, 1, 'B') 
insert into @tmp (id,subid,txt) values (2, 2, 'B') 
insert into @tmp (id,subid,txt) values (2, 3, 'Q') 

Решение

Select id, fold = (Select cast(txt as varchar(100)) from @tmp t2 where t1.id = t2.id for xml path(''))
from @tmp t1
group by t1.id
0 голосов
/ 11 ноября 2008

Обернуть это в функцию для одного выполнения ...

DECLARE @returnValue varchar(4000)

SELECT @returnValue = ISNULL(@returnValue + ', ' +  myTable.text, myTable.text)
FROM myTable 

RETURN @returnValue

Для небольшого количества записей это сработает ... больше 5 или 10 - это слишком много для функции SQL, и ее нужно переместить на уровень приложения, как предлагали другие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...