Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fold in T-SQL?

If I have data in the following format

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

And would like it in this format:

 id  fold
 1   HelloWorld!
 2   BBQ

How could I accomplish it in T-SQL?

like image 444
Tom Ritter Avatar asked Nov 10 '08 21:11

Tom Ritter


People also ask

What is query folding in SQL?

Query folding is the ability for a Power Query query to generate a single query statement to retrieve and transform source data. The Power Query mashup engine strives to achieve query folding whenever possible for reasons of efficiency.

What does \t mean in SQL?

T-SQL (Transact-SQL) is a set of programming extensions from Sybase and Microsoft that add several features to the Structured Query Language (SQL), including transaction control, exception and error handling, row processing and declared variables.

What is #table in SQL?

Tables are database objects that contain all the data in a database. In tables, data is logically organized in a row-and-column format similar to a spreadsheet. Each row represents a unique record, and each column represents a field in the record.

What is SQL Server optimizer?

The SQL Server Query Optimizer is a cost-based optimizer. Each possible execution plan has an associated cost in terms of the amount of computing resources used. The Query Optimizer must analyze the possible plans and choose the one with the lowest estimated cost.


2 Answers

I would strongly suggest against that. That is the sort of thing that should be handled in your application layer.

But... if you must:
Concatenating Row Values in Transact-SQL

like image 99
LeppyR64 Avatar answered Oct 05 '22 09:10

LeppyR64


a temp table and a cursor leap to mind...

Dear Downvoters: a temp table and a cursor have got to be at least as efficient as the recursive-query and custom-function solutions accepted above. Get over your fear of cursors, sometimes they are the most efficient solution. Sometimes they are the only solution. Deal with it.

EDIT: cursor-based solution below. Note that it has none of the limitations of the non-cursor (and more complicated) solutions proposed elsewhere, and performance is probably about the same (hard to tell from a six-row table of course).

and please, don't abandon the main for-each construct of sql just because some blogger says "it's bad"; use your own judgement and some common sense. I avoid cursors whenever possible, but not to the point where the solution is not robust.

--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
like image 31
3 revs Avatar answered Oct 05 '22 07:10

3 revs