SQL Server 2012中如何在查询中使用不存在的列?
这问题我太熟了!你踩的是SQL执行顺序的典型坑——SELECT子句里定义的列别名,没办法在同一个SELECT的其他表达式里直接引用。因为SQL的执行逻辑是先处理FROM/JOIN/WHERE这些环节,最后才会生成SELECT里的列,所以当你在第二个CASE里调用[Pay_Type]时,SQL还没识别到这个别名呢,自然就报“无效列名”的错误了。
给你三种可行的解决办法,按需选就行:
方法1:用CTE(公共表表达式)拆分逻辑
先把Pay_Type的计算结果封装到一个临时的逻辑表中,再在主查询里直接引用这个别名,可读性和维护性都最好:
WITH PersonPayInfo AS ( SELECT sp.First_Name, -- 先计算出Pay_Type的值 CASE WHEN NOT EXISTS(SELECT '1' FROM PERSON_SALARY ps WHERE ps.PARTY_ID = sp.PARTY_ID and ps.END_DATE IS NULL) THEN 'Hourly' ELSE 'Salary' END AS Pay_Type, pj.HOURLY_RATE FROM SEC_PERSON sp LEFT OUTER JOIN PERSON_JOB pj ON sp.PERSON_ID = pj.PERSON_ID WHERE sp.END_DATE IS NOT NULL ) SELECT First_Name, Pay_Type, -- 直接引用CTE里的Pay_Type CASE WHEN Pay_Type = 'Hourly' THEN HOURLY_RATE ELSE '0.00' END AS HOURLY_RATE FROM PersonPayInfo;
方法2:用子查询实现(和CTE逻辑一致)
如果你的SQL环境对CTE支持有限,用子查询也能达到同样效果:
SELECT First_Name, Pay_Type, CASE WHEN Pay_Type = 'Hourly' THEN HOURLY_RATE ELSE '0.00' END AS HOURLY_RATE FROM ( -- 子查询先算出Pay_Type SELECT sp.First_Name, CASE WHEN NOT EXISTS(SELECT '1' FROM PERSON_SALARY ps WHERE ps.PARTY_ID = sp.PARTY_ID and ps.END_DATE IS NULL) THEN 'Hourly' ELSE 'Salary' END AS Pay_Type, pj.HOURLY_RATE FROM SEC_PERSON sp LEFT OUTER JOIN PERSON_JOB pj ON sp.PERSON_ID = pj.PERSON_ID WHERE sp.END_DATE IS NOT NULL ) AS SubQuery;
方法3:直接重复CASE逻辑(简单但冗余)
如果逻辑比较简单,不想写子查询/CTE,也可以把Pay_Type的判断逻辑直接复制到第二个CASE里,缺点是以后修改判断条件时要改两处,容易遗漏:
SELECT sp.First_Name, CASE WHEN NOT EXISTS(SELECT '1' FROM PERSON_SALARY ps WHERE ps.PARTY_ID = sp.PARTY_ID and ps.END_DATE IS NULL) THEN 'Hourly' ELSE 'Salary' END AS Pay_Type, HOURLY_RATE = CASE -- 重复Pay_Type的判断逻辑 WHEN NOT EXISTS(SELECT '1' FROM PERSON_SALARY ps WHERE ps.PARTY_ID = sp.PARTY_ID and ps.END_DATE IS NULL) THEN pj.HOURLY_RATE ELSE '0.00' END FROM SEC_PERSON sp LEFT OUTER JOIN PERSON_JOB pj ON sp.PERSON_ID = pj.PERSON_ID WHERE sp.END_DATE IS NOT NULL;
个人更推荐前两种方法,尤其是CTE,代码结构清晰,后续维护起来省心。
内容的提问来源于stack exchange,提问作者Massey
相关产品推荐
相关产品推荐

