【问题标题】:Using column value as column name in subquery在子查询中使用列值作为列名
【发布时间】:2017-10-11 03:07:43
【问题描述】:

我正在使用一个遗留数据库,该数据库有一个表,其中包含其他表中的字段名称。

所以我有这个结构:

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?

【问题讨论】:

  • 一个表有,而不是字段
  • 立即执行或类似操作,具体取决于您的 RDBMS
  • @jarlh - 明白。我没有编写原始架构,也没有更改它的选项。在这种情况下,列的名称是 Field_Name 等
  • @Randy - MSSQL, sql server 2016 我相信
  • 什么风格和版本的 SQL?

标签: sql sql-server sql-server-2008 tsql unpivot


【解决方案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)

【讨论】:

  • 演示按预期工作,但有一点问题......我简化了我的例子。真实世界的版本需要在两个不同的表中查找 'value' tblUsers 和 tblusers_program_history_detail。我可以加入他们,但 sql 会抱怨,因为它上面有两个 user_id 实例
  • 我正在使用的动态sql语句:select Field_ID ,(case when DB_Field_Name is null then Field_Name else DB_Field_Name end) as FieldName ,Field_Name ,DB_Field_Name ,Proper_Label ,FieldCategory ,FieldValue from dbo.tblBiographic_Fields f join (SELECT * from (select * from tblUsers u inner join tblusers_program_history_detail h on u.User_ID = h.User_ID where h.User_ID = 1) src unpivot (FieldValue for field in (' + @cols + ')) up )t on t.field = DB_Field_Name
  • @SamR。您还可以查看 tblUserstblusers_program_history_detail 的联合以获取相关列
  • 您应该在此处明确放置列列表而不是 * :select * from tblUsers u inner join tblusers_program_history_detail
  • 表的联合列数是否必须相同?
猜你喜欢
  • 2021-04-19
  • 2017-03-21
  • 1970-01-01
  • 2021-03-20
  • 2018-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-23
相关资源
最近更新 更多