我正在尝试在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'中的值识别为列标题而不是子查询中的变量?
答案 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