Sql 在子查询中将一个字段的值用作列名

Sql 在子查询中将一个字段的值用作列名,sql,sql-server,database,Sql,Sql Server,Database,我试图在SQL中计算一个查询,根据对多个字段之一的答案,从辅助表中选择记录。特定字段因记录而异,因此我需要使用初始查询中的值作为第二次查询中的列标题 我有三张表(本例简化) 通过表: PassID | PassType | PersonID | 1 | 3 | 54 | 2 | 4 | 59 | 资格要求表: PassType | QualificationField | Qualification

我试图在SQL中计算一个查询,根据对多个字段之一的答案,从辅助表中选择记录。特定字段因记录而异,因此我需要使用初始查询中的值作为第二次查询中的列标题

我有三张表(本例简化)

通过表:

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
本质上不同的通行证有不同的标准,使他们有资格获得额外的。。。我需要确定的是,对于每个人,他们是否具有基于分配给他们的合格证的资格标准

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

我已经有了一个查询(Q_PersonWithPass),该查询与pass类型和资格要求相匹配,以便在一个输出中为我提供以下字段:

PersonID | PassType | QualificationField | QualificationAnswer
54       | 3        | Q8                 | Yes
59       | 4        | Q3                 | All
我现在需要做的是在person表上运行一个子查询,以查找与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”,而不是回答“否”或“全部”


有没有一种方法可以让SQL将“dbo.Q\u PersonWithPass.QualificationField”中的值识别为列标题而不是子查询中的变量?

正如在答案下面的一条注释中所提到的,我认为唯一的方法是生成一个动态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;

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

正如回答下面的一条评论中所提到的,我认为实现所需的唯一方法是生成动态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;

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

不确定您到底想要什么结果,但您可以通过使用
案例
实现您想要做的事情。大致如下:

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

不确定结果是什么,但您可以通过使用
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

我认为这是不可能的。您可以构建动态SQL查询并使用sp_executesql执行最终查询字符串。我认为这是不可能的。您可以构建动态SQL查询并使用sp_executesql执行最终查询字符串。问题是,可以将列动态添加到Person表中。如果发生这种情况,我认为这会阻止您编写一个保证工作的显式case语句?在问题中,它说可以将列动态添加到Person表中。如果发生这种情况,我认为这将阻止你写一个明确的案例声明,保证工作?嗨,谢谢!我曾经尝试过动态sql,但没有太多地使用它,我不知道如何让它工作。我只需要对您的代码进行一次编辑,
PWP.QualificationField='+@QField+'
周围的引号必须是
PWP.QualificationField=''+@QField+'
,但之后一切都很好!Cheers这个想法是,您只是试图构造要运行到变量@SQLQuery中的sql语句,然后在末尾执行它。如果在最后一个end语句之前添加“print@SQLQuery”,它将打印出查询试图运行的内容。我不确定您现在尝试时是否收到错误消息,或者它根本不起作用?嗨,它现在起作用了,谢谢!我按照你的建议打印了这张照片,以发现对报价的需求。非常感谢。虽然这在我执行它时效果很好,但我看不到一种方法可以使用它来输入其他保存的“视图”。我可以让它作为存储过程运行,但这不会反馈给我的其他查询。我已经尝试将其插入到表值函数中,但这不允许我执行动态sql。是否有一种方法可以解决这个问题,或者通常没有方法将动态sql结果反馈到另一个查询中?您好,谢谢!我曾经尝试过动态sql,但没有太多地使用它,我不知道如何让它工作。我只需要对您的代码进行一次编辑,
PWP.QualificationField='+@QField+'
周围的引号必须是
PWP.QualificationField=''+@QField+'
,但之后一切都很好!Cheers这个想法是,您只是试图构造要运行到变量@SQLQuery中的sql语句,然后在末尾执行它。如果在最后一个end语句之前添加“print@SQLQuery”,它将打印出查询试图运行的内容。我不确定您现在尝试时是否收到错误消息,或者它根本不起作用?嗨,它现在起作用了,谢谢!我按照你的建议打印了这张照片,以发现对报价的需求。非常感谢。虽然这在我执行它时效果很好,但我看不到一种方法可以使用它来输入其他保存的“视图”。我可以让它作为存储过程运行,但这不会反馈给我的其他查询。我已经尝试将其插入到表值函数中,但这不允许我执行动态sql。有办法绕过t吗