与光标连接

not*_*kie 1 t-sql sql-server string-concatenation cursor

我真的很想学习和理解如何使用游标方法连接字符串。

这是我的表:

declare @t table (id int, city varchar(15))
insert into @t values 
    (1, 'Rome')
    ,(1, 'Dallas')
    ,(2, 'Berlin')
    ,(2, 'Rome')
    ,(2, 'Tokyo')
    ,(3, 'Miami')
    ,(3, 'Bergen')
Run Code Online (Sandbox Code Playgroud)

我正在尝试创建一个表,其中包含按字母顺序排序的一行中每个 ID 的所有城市。

ID  City
1   Dallas, Rome
2   Berlin, Rome, Tokyo
3   Bergen, Miami
Run Code Online (Sandbox Code Playgroud)

到目前为止,这是我的代码,但它不起作用,如果有人能引导我完成每一步,我会非常高兴并渴望学习它!

set nocount on
declare @tid int
declare @tcity varchar(15)



declare CityCursor CURSOR FOR
    select * from @t 
    order by id, city

   open CityCursor

   fetch next from CityCursor into @tid, @tcity

   while ( @@FETCH_STATUS = 0)
   begin

        if @tid = @tid -- my idea add all cities in one line within each id
            print cast(@tid as varchar(2)) + ', '+ @tcity 
        else if @tid <> @tid --when it reaches a new id and we went through all cities it starts over for the next line
        fetch next from CityCursor into @tid, @tcity
   end

   close CityCursor
   deallocate CityCursor

   select * from CityCursor
Run Code Online (Sandbox Code Playgroud)

Zoh*_*led 5

首先,对于未来的读者:正如肖恩·兰格 (Sean Lange) 在评论中所写的那样,光标是完成这项工作的错误工具。正确的方法是使用带有for xml.

但是,由于您想知道如何使用游标进行操作,因此您实际上非常接近。这是一个工作示例:

set nocount on
declare @prevId int, 
        @tid int,
        @tcity varchar(15)

declare @cursorResult table (id int, city varchar(32)) 
-- if you are expecting more than two cities for the same id, 
-- the city column should be longer

declare CityCursor CURSOR FOR
select * from @t 
order by id, city

open CityCursor

fetch next from CityCursor into @tid, @tcity

while ( @@FETCH_STATUS = 0)
begin

    if @prevId is null or @prevId != @tid 
        insert into @cursorResult(id, city) values (@tid, @tcity)
    else 
        update @cursorResult
        set city = city +', '+ @tcity
        where id = @tid

    set @prevId = @tid    
    fetch next from CityCursor into @tid, @tcity
end

close CityCursor
deallocate CityCursor

select * from @cursorResult
Run Code Online (Sandbox Code Playgroud)

结果:

id  city
1   Dallas, Rome
2   Berlin, Rome, Tokyo
3   Bergen, Miami
Run Code Online (Sandbox Code Playgroud)

我使用了另一个变量来保留以前的 id 值,并将游标的结果插入到表变量中。