2017-10-10 7 views
2

Je travaille avec une base de données héritée dont la table contient des noms de champs provenant d'autres tables.Utilisation de la valeur de colonne en tant que nom de colonne dans la sous-requête

J'ai donc cette structure:

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

et je dois tirer une liste de ces métadonnées sur le terrain ainsi que les valeurs de ce champ pour un utilisateur donné. Donc, j'ai besoin:

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

Je voudrais utiliser le Field_Name dans une sous-requête pour tirer cette valeur, mais ne peut pas comprendre comment obtenir SQL pour évaluer Field_Name comme une colonne dans la sous-requête.

donc quelque chose comme ceci:

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

Mais qui vient retourne Field_Name dans la colonne des valeurs, pas la valeur de celui-ci.

Ai-je besoin de mettre la sous-requête dans une fonction séparée et d'évaluer cela? Ou une sorte de SQL dynamique?

+0

Une table a _columns_, non _fields_. – jarlh

+0

EXECUTE IMMEDIATE ou similaire selon votre SGBDR – Randy

+0

@jarlh - compris. Je n'ai pas écrit le schéma d'origine et je n'ai pas la possibilité de le changer. Les noms des colonnes dans ce cas sont Field_Name, etc –

Répondre

1

Dans SQL Server, cela nécessiterait une notation SQL dynamique et 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

demo fonctionne comme prévu, mais une ride ... J'ai simplifié mon exemple. La version du monde réel doit regarder dans deux tables différentes pour 'tblUsers' value et tblusers_program_history_detail. Je peux les rejoindre mais sql se plaint parce qu'il a deux instances de user_id sur elle –

+0

l'instruction SQL dynamique J'utilise: 'select FIELD_ID \t, (cas où DB_Field_Name est nul alors Field_Name autre DB_Field_Name fin) comme FieldName \t, Field_Name \t, DB_Field_Name , Proper_Label , FieldCategory \t, FieldValue de dbo.tblBiographic_Fields f rejoindre (SELECT * de \t \t \t (select * from tblUsers u jointure interne tblusers_program_history_detail h \t sur u.User_ID = h.User_ID \t où h.User_ID = 1) src \t \t \t UNPIVOT (FieldValue pour le champ dans ('+ +' @cols)) vers le haut) t \t \t \t sur t .field = DB_Field_Name' –

+0

@SamR. vous pouvez également regarder dans l'union de 'tblUsers' et' tblusers_program_history_detail' pour les colonnes pertinentes – DhruvJoshi