0

このような別のテーブルの列IDに基づいて、複数の列を持つテーブルの値を選択しようとしています

foo:
+-------+--------+--------+--------+
|  id   |  tag   | col1   |  col2  |
+-------+--------+--------+--------+
|   1   |   XX   |    1   |    2   |
+-------+--------+--------+--------+
bar:
+-------+--------+--------+
| id    | field  |  tag   |
+-------+--------+--------+
|   1   |  col1  |   XX   |
+-------+--------+--------+
|   2   |  col2  |   XX   |
+-------+--------+--------+

私が探しているのは、リフレクションのようなメカニズムだと思います。列は時間の経過とともに変化する可能性があるため、クラスやテーブルについて事前に知る必要なく、そのプロパティの名前に基づいてプロパティ値にマップできます。結果のテーブルは次のようになります

foobar:
+--------+--------+
|  tag   | value  |
--------++--------+
|   XX   |    1   |
--------++--------+
|   XX   |    2   |
--------++--------+

以下のコードのようなものを試してみましたが、両方の結果列に列 ID が表示されます。列の名前ではなく、その特定のフィールドの値が必要です。

declare @SQL nvarchar(max)
declare @Pattern nvarchar(100)

set @Pattern = 'select bar.field, ''foo.[COL_NAME]'' as CurrentValue FROM bar INNER JOIN foo ON foo.[tag] = bar.[tag]'

select @SQL = stuff((select ' union all '+replace(@Pattern, '[COL_NAME]', field)
                 from bar
                 for xml path(''), type).value('.', 'nvarchar(max)'), 1, 11, '')

exec (@SQL)
4

1 に答える 1

1

単一の SQL ステートメントで動的に実行できるとは思わないでください。しかし、動的SQLでそれを行うことができます。

与えられたデータセットで、目的の結果を得る最も簡単な方法は、case ステートメントを使用することです。

select foo.tag, 
case 
    when bar.field = 'col1' then foo.col1
    when bar.field = 'col2' then foo.col2
    else null
end as value
from foo
    inner join bar on foo.tag = bar.tag

部分だけwhen...then...が動的ですが、残りは静的です。したがって、barテーブルをループして動的部分を構築し、それをすべて連結します。

declare @sql varchar(2000)
set @sql=''
select @sql = @sql +' when bar.field='''+field+''' then foo.' + field
from (select distinct field from bar) sub

--print @sql

set @sql = 'select foo.tag, 
case ' + @sql  + ' 
    else null
end as value
from foo
    inner join bar on foo.tag = bar.tag'

--print @sql

exec(@sql)
于 2013-04-11T20:28:27.110 に答える