1

我正在尝试将来自不同(或与此示例相同)表的结果组合到单独的列中(作为例如 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 的情况下解决这个问题?

4

1 回答 1

2

AFAIK,不,你不能没有动态 SQL。PIVOT但是,如果您使用table 运算符,它会更简单,如下所示:

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

SQL 小提琴演示

要动态地做到这一点,它将是这样的:

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 |

更新的 SQL Fiddle 演示

于 2013-02-22T12:57:19.600 回答