2017-10-10 123 views
2

我正在处理一个遗留数据库,该数据库有一个表格,其中包含来自其他表的字段名称。使用列值作为子查询中的列名称

所以我有这样的结构:

Field_ID | Field_Name 
********************* 
1 | Col1 
2 | Col2 
3 | Col3 
4 | Col4 

,我需要拉动该领域元数据的列表与字段的给定用户的值一起。所以,我需要:

Field_ID | Field_Name | Value 
1 | Col1 | ValueOfCol1onADiffTable 
2 | Col2 | ValueOfCol2onADiffTable 
3 | Col3 | ValueOfCol3onADiffTable 
4 | Col4 | ValueOfCol4onADiffTable 

我想用FIELD_NAME在子查询中拉该值,但无法弄清楚如何获得SQL评估Field_Name作为子查询的列。

因此,像这样:

select 
     Field_ID 
     ,Field_Name 
     ,(SELECT f.Field_Name from tblUsers u 
    where u.User_ID = @userId) as value 
from 
    dbo.tblFields f 

但只返回Field_Name在值列,而不是它的价值。

我是否需要将子查询放入单独的函数中并对其进行评估?或者某种动态SQL?

+0

桌子有_columns_,不_fields_。 – jarlh

+0

执行立即或类似取决于您的RDBMS – Randy

+0

@jarlh - 理解。我没有写出原始模式,也没有改变它的选项。在这种情况下列的名称是Field_Name等 –

回答

1

在SQL服务器中,这需要动态SQL和UNPIVOT表示法。 see working demo

create table tblFields (Field_ID int ,Field_Name varchar(10)); 
insert into tblFields values 
(1,'Col1') 
,(2,'Col2') 
,(3,'Col3') 
,(4,'Col4'); 
declare @userId int 
set @userId=1 

create table tblUsers (User_ID int, col1 varchar(10),col2 varchar(10)); 
insert into tblUsers values 
(1, 10,100), 
(2,20,200); 

declare @collist varchar(max) 
declare @sqlquery varchar(max) 

select @collist= COALESCE(@collist + ', ', '') + Field_Name 
from dbo.tblFields 
where exists (
     select * from sys.columns c join sys.tables t 
     on c.object_id=t.object_id and t.name='tblUsers' 
     and c.name =Field_Name) 
select @sqlquery= 
' select Field_ID ,Field_Name, value '+ 
' from dbo.tblFields f Join '+ 
' (select * from '+ 
'(select * '+ 
' from tblUsers u '+ 
' where u.User_ID = '+ cast(@userId as varchar(max)) + 
') src '+ 
'unpivot (Value for field in ('+ @collist+')) up)t'+ 
' on t.field =Field_Name' 
exec(@sqlquery) 
+0

演示按预期工作,但一个皱纹...我简化了我的例子。真实世界的版本需要在两个不同的表中查找'value'tblUsers和tblusers_program_history_detail。我可以加入他们,但那么SQL抱怨,因为它有USER_ID的两个实例就可以了 –

+0

动态SQL语句我使用: '选择FIELD_ID \t,(情况下,当DB_Field_Name为null,则FIELD_NAME其他DB_Field_Name结束)作为字段名 \t,FIELD_NAME \t,DB_Field_Name ,Proper_Label ,FieldCategory \t,fieldValue方法 从 dbo.tblBiographic_Fields˚F 加入(SELECT *从 \t \t \t(SELECT * FROM向tblUsersù内部联接tblusers_program_history_detail H于u.User_ID = h.User_ID \t \t 其中h.User_ID = 1)的src \t \t \t逆转置(fieldValue方法在( '+ @cols +' 字段))向上)吨 \t \t \t上吨.field = DB_Field_Name' –

+0

@SamR。您也可以查看相关列的'tblUsers'和'tblusers_program_history_detail'的联合体 – DhruvJoshi

相关问题