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ただし、次のようにテーブル演算子を使用すると、はるかに簡単になります。

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フィドルデモ

于 2013-02-22T12:57:19.600 に答える