使用一个字段的值作为子查询中的列名

时间:2016-05-10 10:41:45

标签: sql sql-server database

我正在尝试在SQL中编写一个查询,根据对许多字段之一的答案,从辅助表中选择记录。特定字段因记录而异,因此我需要在初始查询中使用VALUE作为我的辅助查询中的COLUMN标题。

我有三个表(本例简化)

传递表:

PassID  |  PassType  | PersonID |
1       |  3         | 54       |
2       |  4         | 59       |

资格要求表:

PassType  |  QualificationField |  QualificationAnswer
3         |  Q8                 |  Yes
4         |  Q3                 |  All

人员表:

PersonID  |  Name  |...| Q3  |...| Q8   
54        |  John  |...| Non |...| No
59        |  Jane  |...| ALL |...| No

基本上不同的传球有不同的标准,使他们有资格获得额外的东西......我需要确定的是每个人,如果他们有基于他们被分配的传球的资格标准。

这些表实际上是更大系统的一部分,人员表中的列可以在数据库的不同迭代中动态添加,因此我无法显着更改表结构 - 我需要能够提取我的答案在SQL查询中确定哪些人有资格获得“额外的东西”。

我已经有一个与传递类型和资格要求相匹配的查询(Q_PersonWithPass),在一个输出中给我以下字段:

PersonID | PassType | QualificationField | QualificationAnswer
54       | 3        | Q8                 | Yes
59       | 4        | Q3                 | All

我现在需要做的是在人员表上运行子查询以查找与QualificationField答案相关的列,并检查Person表中的该字段是否与QualificationAnswer匹配。

我试过这个:

SELECT        PersonID, PassType, QualificationField, QualificationAnswer,
               (SELECT dbo.Q_PersonWithPass.QualificationField
                FROM dbo.Person
                WHERE  (PersonID = dbo.Q_PersonWithPass.PersonID)) AS QualFld
FROM            dbo.Q_PersonWithPass

因此只在QualFld中显示“Q8”或“Q3”而不是答案“No”或“All”

有没有办法让SQL能够将'dbo.Q_PersonWithPass.QualificationField'中的值识别为列标题而不是子查询中的变量?

2 个答案:

答案 0 :(得分:0)

正如在答案中的一条评论中所提到的,我认为实现所需的唯一方法是生成动态SQL查询。下面的代码可能不是按键完美,但它应该让你知道该怎么做。

这个想法是你计算出所有可能的资格字段,将它们插入一个临时表,然后根据所有可用的选项动态地构建一个case语句。

Select Distinct QualificationField
  Into #TEMPTABLE
  From dbo.Q_PersonWithPass;

DECLARE
@SQLQuery nvarchar(4000),
@QField nvarchar(10)
BEGIN

Set @SQLQuery = 'select PWP.PersonId, PWP.PassType, PWP.QualificationField, PWP.QualificationAnswer,  Case ';

While EXISTS(Select * from #TEMPTABLE)
Begin
    Select Top 1 @QField = QualificationField From #TEMPTABLE;
    Set @SQLQuery = @SQLQuery + 'When PWP.QualificationField = ' + @QField + ' Then P.' + @QFIELD + ' ';
    Delete from #TEMPTABLE Where QualificationField = @QField;
End

Set @SQLQuery = @SQLQuery + ' end AS QualFld FROM dbo.Q_PersonWithPass PWP JOIN dbo.Person P on P.PersonID = PWP.PersonID';

EXECUTE sp_executesql  @SQLQuery

END;

如果您有任何问题,请告诉我。

答案 1 :(得分:0)

不确定您想要的结果是什么,但是您可以使用CASE来实现您想要做的事情。有点像这样:

SELECT PersonID, PassType, QualificationField, QualificationAnswer,
    (CASE When p.PersonID = dbo.Q_PersonWithPass.PersonID then 'Yes' 
    else 'No' end ) ASQualFld
    FROM dbo.Q_PersonWithPass LEFT JOIN Person p on p.PersonID = dbo.Q_PersonWithPass.PersonID