SQL Server 2005合并存在多个行的行

时间:2013-09-18 12:33:56

标签: sql-server sql-server-2005

我有一张这样的表:

    select * from tbRegInfo
    clubID  personID    Sex Birth Year  Birth Month JoinedDate  leftDate
    C77     745         M   1942        5           14/05/2002  09/09/2010
    C77     246         M   2008        5           15/04/2009  14/01/2011
    C77     246         M   2008        5           16/09/2008  27/10/2008
    C77     59          M   1941        5           07/09/2011  24/01/2012
    C77     498         F   1945        1           12/03/2011  NULL
    C77     478         M   1935        6           07/06/2010  NULL
    B92     367         F   1955        8           18/10/1988  NULL
    B92     84          M   2006        6           03/07/2008  NULL
    B92     836         M   1965        7           07/11/2008  18/01/2013
    B92     833         F   1962        4           13/01/1995  13/03/2000
    B92     833         F   1962        4           05/09/2002  NULL

有些人在表格中有超过1行,因为他们已经加入,离开并再次加入。我想生成像这样的查询

    clubID  personID    Sex BirthYear   BirthMonth  JoinedDate  leftDate    joinedDate2 leftDate2
    C77     745         M   1942        5           14/05/2002  09/09/2010      
    C77     246         M   2008        5           15/04/2009  14/01/2011  16/09/2008  27/10/2008
    C77     59          M   1941        5           07/09/2011  24/01/2012      
    C77     498         F   1945        1           12/03/2011          
    C77     478         M   1935        6           07/06/2010          
    B92     367         F   1955        8           18/10/1988          
    B92     84          M   2006        6           03/07/2008          
    B92     836         M   1965        7           07/11/2008  18/01/2013      
    B92     833         F   1962        4           13/01/1995  13/03/2000  05/09/2002  

其中,如果存在第二个加入日期,则该值将显示在同一行的另一列中。我意识到我需要在选择时加入,但我无法弄清楚如何做到这一点

1 个答案:

答案 0 :(得分:0)

这是一篇很长篇文章:) 1-选择不带JoinedDate和leftDate的distint列 2-创建包含其他列的唯一列(Id列)

 select 
 distinct [clubID],[personID],[Sex],[Birth Year],[Birth Month],
 ([clubID] +'-'+ convert(nvarchar,[personID]) +'-'+ convert(nvarchar,[Sex])+'-'+ 
 convert(nvarchar,[Birth Year]) + '-' +convert(nvarchar,[Birth Month])) as Id   
 into #dt 
 from tbRegInfo

3-为select JoinedDate

创建其他临时表
SELECT   b.JoinedDate, a.Id, COUNT(*) AS Count
into #dt2       
FROM            dbo.#dt AS a INNER JOIN
dbo.tbRegInfo AS b ON 
(b.[clubID] +'-'+ convert(nvarchar,b.[personID]) +'-'+ 
convert(nvarchar,b.[Sex])+'-'+ convert(nvarchar,b.[Birth Year]) 
+ '-' +convert(nvarchar,b.[Birth Month]))=a.Id

GROUP BY b.JoinedDate, a.Id
ORDER BY Count

4-为JoinedDate添加列。它将为最大重复的JoinedDate添加列。我的意思是如果一个人5次加入并离开。它会加上

JoinedDate,JoinedDate1,JoinedDate2,JoinedDate ... JoinedDate5

 declare @Id nvarchar(250) = ''
 declare @date date
 declare @count int
 declare @counter int =2
 declare @mySql nvarchar(4000)=''

  ALTER TABLE #dt ADD JoinedDate date

  select @count =max(Count) from #dt2

  while @counter<=@count
  begin

    set @mySql =  'ALTER TABLE #dt ADD JoinedDate' 
       + convert(nvarchar,@counter-1) + ' date '
    exec (@mySql )

    set @counter= @counter+1
  end

5-使用游标将Joineddate添加到相关列

DECLARE my_cursor  CURSOR FOR select Id, JoinedDate, Count from #dt2 
    open my_cursor
    FETCH NEXT FROM my_cursor INTO  @Id,@date,@count
    WHILE @@FETCH_STATUS =0
        BEGIN

        set @counter=1
                set @mySql=''
                while @counter<=@count
                begin
                    if  @counter=1
                    begin
        set @mySql =  ' update #dt set JoinedDate =  ' + char(39) + 
            convert(nvarchar,@date) + char(39) + ' where Id= ' 
            +  char(39) +  @Id +  char(39)
                    end
                    else
                    begin
                        set @mySql =  ' update #dt set 
                     JoinedDate' + convert(nvarchar,@counter-1)  + '  =  ' 
                     + char(39) +  convert(nvarchar,@date) + char(39) + ' 
                       where Id= ' +  char(39) +  @Id +  char(39)
                    end
                     exec (@mySql )

                    set @counter= @counter+1
                end

    FETCH NEXT FROM my_cursor INTO   @Id,@date,@count
END

close my_cursor
deallocate my_cursor

------------ JOINEDDATE现已完成LEFTDATE开始----

1-使用join #dt

插入leftdate临时表
SELECT        b.leftDate, a.Id, COUNT(*) AS Count
into #dt3       
FROM            dbo.#dt AS a INNER JOIN
dbo.tbRegInfo AS b ON 
(b.[clubID] +'-'+ convert(nvarchar,b.[personID]) +'-'
 + convert(nvarchar,b.[Sex])+'-'+ convert(nvarchar,b.[Birth Year]) 
  + '-' +convert(nvarchar,b.[Birth Month]))=a.Id

GROUP BY b.leftDate, a.Id
ORDER BY Count

2-为Leftdate添加列

  ALTER TABLE #dt ADD LeftDate date

    select @count =max(Count) from #dt3

  set @mySql =''
   set @counter=2
  while @counter<=@count
  begin

    set @mySql =  'ALTER TABLE #dt ADD LeftDate' 
     + convert(nvarchar,@counter-1) + ' date '
    exec (@mySql )

    set @counter= @counter+1
  end

3-使用光标

将Leftdate插入#dt
DECLARE my_cursor_sec  CURSOR FOR select distinct Id, LeftDate,Count from #dt3  
    open my_cursor_sec
    FETCH NEXT FROM my_cursor_sec INTO  @Id,@date,@count
    WHILE @@FETCH_STATUS =0
        BEGIN

                set @counter=1
                set @mySql=''
                while @counter<=@count
                begin
                    if  @counter=1
                    begin
         set @mySql =  ' update #dt set LeftDate =  ' 
                  + char(39) +  convert(nvarchar,@date) + char(39) 
                  + ' where Id= ' +  char(39) +  @Id +  char(39)
                    end
                    else
                    begin
         set @mySql =  ' update #dt set LeftDate' 
                + convert(nvarchar,@counter-1)  + '  =  ' + char(39) 
                 +  convert(nvarchar,@date) + char(39) + ' where Id= ' 
                   +  char(39) +  @Id +  char(39)
                    end
                         exec (@mySql )

                    set @counter= @counter+1
                end

    FETCH NEXT FROM my_cursor_sec INTO   @Id,@date,@count
END

close my_cursor_sec
deallocate my_cursor_sec

4-现在我们不需要Id列

ALTER TABLE #dt  DROP COLUMN Id

5-最后选择行

select distinct * from #dt

- 结果

clubID   personID    Sex  Birth Year  Birth Month JoinedDate LeftDate
-------- ----------- ---- ----------- ----------- ---------- ----------
B92      84          M    2006        6           2008-07-03 NULL
B92      367         F    1955        8           1988-10-18 NULL
B92      833         F    1962        4           2002-09-05 2000-03-13
B92      836         M    1965        7           2008-11-07 2013-01-18
C77      59          M    1941        5           2011-09-07 2012-01-24
C77      246         M    2008        5           2009-04-15 2011-01-14
C77      478         M    1935        6           2010-06-07 NULL
C77      498         F    1945        1           2011-03-12 NULL
C77      745         M    1942        5           2002-05-14 2010-09-09