代码之家  ›  专栏  ›  技术社区  ›  Tom Ritter

折叠T-SQL?

  •  4
  • Tom Ritter  · 技术社区  · 17 年前

    如果我有以下格式的数据

     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 回复  |  直到 17 年前
        1
  •  10
  •   Martin Smith    12 年前

    我强烈反对这样做。这是应该在应用程序层中处理的事情。

    但是如果必须:
    Concatenating Row Values in Transact-SQL

        2
  •  2
  •   Steven A. Lowe    17 年前

    亲爱的投票人:临时表和游标必须至少和上面接受的递归查询和自定义函数解决方案一样有效。克服对光标的恐惧,有时候它们是最有效的解决方案。有时,它们是唯一的解决办法。处理它。

    请不要因为一些博主说“它不好”就放弃sql的每个构造的main;运用你自己的判断和一些常识。我尽可能避免使用游标,但不会达到解决方案不健壮的程度。

    --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
    
        3
  •  1
  •   user372724 user372724    15 年前
    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
    
        4
  •  0
  •   StingyJack    17 年前

    将其包装在一个函数中,以便执行一次。。。

    DECLARE @returnValue varchar(4000)
    
    SELECT @returnValue = ISNULL(@returnValue + ', ' +  myTable.text, myTable.text)
    FROM myTable 
    
    RETURN @returnValue
    

    对于少量记录,这将起作用。。。任何超过5或10的SQL函数都太多,需要按照其他人的建议将其移动到应用层。