有一张表,名为“TEST”,内容如下:
  F1     F2
-------------------
  A      12
  B      11
  C      11
  A      15
  A      11
  C      12
======================
想将上表转换成如下形式:
 F1   F2   F3   F4
---------------------------
 A    12   15   11
 B    11   
 C    11   12
===========================我该如何写Sql语句?

解决方案 »

  1.   

    select f1 , 
      max(case px when 1 then f2 else 0 end) f2,
      max(case px when 2 then f2 else 0 end) f3,
      max(case px when 3 then f2 else 0 end) f4
    from
    (
      select * , px = (select count(*) from test where f1 = t.f1 and f2 < t.f2) + 1 from test t
    ) m
    group by f1
      

  2.   

    create table tb(F1 varchar(10),   F2 int)
    insert into tb values('A' ,     12 )
    insert into tb values('B' ,     11 )
    insert into tb values('C' ,     11 )
    insert into tb values('A' ,     15 )
    insert into tb values('A' ,     11 )
    insert into tb values('C' ,     12 )
    go--如果同一个F1最多只有三个值,用静态SQL。
    select f1 , 
      max(case px when 1 then f2 else 0 end) f2,
      max(case px when 2 then f2 else 0 end) f3,
      max(case px when 3 then f2 else 0 end) f4
    from
    (
      select * , px = (select count(*) from tb where f1 = t.f1 and f2 < t.f2) + 1 from tb t
    ) m
    group by f1/*
    f1         f2          f3          f4          
    ---------- ----------- ----------- ----------- 
    A          11          12          15
    B          11          0           0
    C          11          12          0(所影响的行数为 3 行)*/--如果同一个F1其值个数不固定,用动态SQL。
    declare @sql varchar(8000)
    set @sql = 'select f1 '
    select @sql = @sql + ' , max(case px when ''' + cast(px as varchar) + ''' then f2 else 0 end) [f' + cast(px + 1 as varchar) + ']'
    from (select distinct px from (select * , px = (select count(*) from tb where f1 = t.f1 and f2 < t.f2) + 1 from tb t) m) as a
    set @sql = @sql + ' from (select * , px = (select count(*) from tb where f1 = t.f1 and f2 < t.f2) + 1 from tb t) m group by f1'
    exec(@sql) 
    /*
    f1         f2          f3          f4          
    ---------- ----------- ----------- ----------- 
    A          11          12          15
    B          11          0           0
    C          11          12          0*/drop table tb
      

  3.   

    create table tb(F1 varchar(10),   F2 int)
    insert into tb values('A',12)
    insert into tb values('B',11)
    insert into tb values('C',11)
    insert into tb values('A',15)
    insert into tb values('A',11)
    insert into tb values('C',12)
    goselect bb.F1,
    sum(case when bb.rank=1 then bb.F2 else 0 end) 'F2',
    sum(case when bb.rank=2 then bb.F2 else 0 end) 'F3',
    sum(case when bb.rank=3 then bb.F2 else 0 end) 'F4'
    from (select *,row_number() over(partition by F1 order by F2 Asc) rank from tb) bb
    group by bb.F1F1         F2          F3          F4
    ---------- ----------- ----------- -----------
    A          11          12          15
    B          11          0           0
    C          11          12          0(3 行受影响)