将表结果组合成列

时间:2013-02-22 12:42:16

标签: sql tsql pivot

我试图将来自不同(或与此示例中相同)表的结果组合到单独的列中(作为例如cat(egory)的函数)。如以下示例所示。

给出以下(T-)SQL

create table tab(id int, val float, cat varchar(1))
insert into tab(id, val, cat)
    select 1, 2.1, 'A' union all 
    select 2, 4.3, 'A' union all 
    select 3, 2.1, 'A' union all 
    select 2, 8.9, 'B' union all 
    select 3, 1.4, 'B' union all 
    select 4, 3.3, 'B'

select id
    , (select val from tab tab_a where cat = 'A' AND tab_a.id = tab.id)
    , (select val from tab tab_b where cat = 'B' AND tab_b.id = tab.id)
from tab
group by id
order by id

id  val(A)   val(B) 
1   2.1      null
2   4.3      8.9
3   2.1      1.4
4   null     3.3

这正是我想要的,但是如果cat是可变的(让我们根据用户输入说),这条路线就会失败。那么我可以/必须(?)切换到动态SQL。这就是我想要避免的。有没有动态SQL解决这个问题的任何建议?

1 个答案:

答案 0 :(得分:2)

AFAIK,不,你不能没有动态SQL。但是,如果你使用PIVOT表运算符,它会更加更加自如:

SELECT *
FROM tab t
PIVOT
(
  MAX(val)
  FOR cat IN(A, B)
) AS p

SQL Fiddle Demo

要动态地执行此操作,它将是这样的:

DECLARE @cols AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);

select @cols = STUFF((SELECT distinct ',' +
                        QUOTENAME(cat)
                      FROM tab                      
                      FOR XML PATH(''), TYPE
                     ).value('.', 'NVARCHAR(MAX)') 
                        , 1, 1, '');

SELECT @query = 
  'SELECT *
   FROM tab AS t
   PIVOT
   (
      MAX(val)
      FOR cat IN ( ' + @cols + ' )
    ) AS p;';

EXECUTE( @query);

这会给你:

| ID |      A |      B |
------------------------
|  1 |    2.1 | (null) |
|  2 |    4.3 |    8.9 |
|  3 |    2.1 |    1.4 |
|  4 | (null) |    3.3 |

Updated SQL Fiddle Demo