使用DATEDIFF计算Age后,在CASE逻辑中引用Age报错的解决方法
解决SQL中无法引用SELECT别名在CASE语句中的问题
嘿,这个问题我碰到过好多次了!核心原因是SQL的查询执行顺序:数据库会先处理FROM/JOIN,接着是WHERE、GROUP BY,最后才会执行SELECT子句。你在SELECT里定义的[Age]别名,在同一层的CASE语句执行时还没被创建出来,所以SMSS会标红提示无效列。
给你三个实用的解决方案,按需选择:
方案1:直接重复Age的计算逻辑(最简单直接)
把DATEDIFF(DD,M.[Account Name Birth Date],GETDATE())/365直接代入CASE里,虽然有点重复,但对于简单计算来说很高效:
USE DataWarehouse SELECT DISTINCT M.[Account Name Birth Date] as 'Birth Date', M.[Mailing Address State] as 'State', E.[ANSVIES2] as 'Income', E.[FICO] as 'FICO Score', DATEDIFF(DD,M.[Account Name Birth Date],GETDATE())/365 as [Age], CASE WHEN DATEDIFF(DD,M.[Account Name Birth Date],GETDATE())/365 >= 18 AND DATEDIFF(DD,M.[Account Name Birth Date],GETDATE())/365 <= 34 AND E.[ANSVIES2] >= 50 THEN 'Credit Driven' WHEN DATEDIFF(DD,M.[Account Name Birth Date],GETDATE())/365 < 45 AND E.[ANSVIES2] < 50 THEN 'Fee Driven' WHEN DATEDIFF(DD,M.[Account Name Birth Date],GETDATE())/365 >= 35 AND DATEDIFF(DD,M.[Account Name Birth Date],GETDATE())/365 <= 54 AND E.[ANSVIES2] >= 50 AND E.[ANSVIES2] <= 125 THEN 'Middle Market' WHEN DATEDIFF(DD,M.[Account Name Birth Date],GETDATE())/365 >= 45 AND E.[ANSVIES2] < 50 THEN 'Low Income Depositor' WHEN DATEDIFF(DD,M.[Account Name Birth Date],GETDATE())/365 >= 55 AND E.[ANSVIES2] >= 50 AND E.[ANSVIES2] <= 125 THEN 'Middle Income Depositor' WHEN DATEDIFF(DD,M.[Account Name Birth Date],GETDATE())/365 >= 35 AND E.[ANSVIES2] >= 125 THEN 'Upscale' ELSE 'Unclassified' END as 'Consumer Segment' FROM -- 记得替换成实际表名和关联字段 YourTableM M JOIN YourTableE E ON M.PrimaryKey = E.ForeignKey
方案2:使用CTE(公共表表达式,可读性更高)
先通过CTE算出包含Age的临时数据集,再在后续查询里直接引用这个别名:
USE DataWarehouse WITH CustomerBase AS ( SELECT DISTINCT M.[Account Name Birth Date] as 'Birth Date', M.[Mailing Address State] as 'State', E.[ANSVIES2] as 'Income', E.[FICO] as 'FICO Score', DATEDIFF(DD,M.[Account Name Birth Date],GETDATE())/365 as [Age] FROM YourTableM M JOIN YourTableE E ON M.PrimaryKey = E.ForeignKey -- 替换成实际关联字段 ) SELECT *, CASE WHEN [Age] >= 18 AND [Age] <= 34 AND Income >= 50 THEN 'Credit Driven' WHEN [Age] < 45 AND Income < 50 THEN 'Fee Driven' WHEN [Age] >= 35 AND [Age] <= 54 AND Income >= 50 AND Income <= 125 THEN 'Middle Market' WHEN [Age] >= 45 AND Income < 50 THEN 'Low Income Depositor' WHEN [Age] >= 55 AND Income >= 50 AND Income <= 125 THEN 'Middle Income Depositor' WHEN [Age] >= 35 AND Income >= 125 THEN 'Upscale' ELSE 'Unclassified' END as 'Consumer Segment' FROM CustomerBase
方案3:使用子查询(和CTE效果类似)
把基础查询包在子查询里,外层查询就能直接引用Age别名了:
USE DataWarehouse SELECT *, CASE WHEN [Age] >= 18 AND [Age] <= 34 AND Income >= 50 THEN 'Credit Driven' WHEN [Age] < 45 AND Income < 50 THEN 'Fee Driven' WHEN [Age] >= 35 AND [Age] <= 54 AND Income >= 50 AND Income <= 125 THEN 'Middle Market' WHEN [Age] >= 45 AND Income < 50 THEN 'Low Income Depositor' WHEN [Age] >= 55 AND Income >= 50 AND Income <= 125 THEN 'Middle Income Depositor' WHEN [Age] >= 35 AND Income >= 125 THEN 'Upscale' ELSE 'Unclassified' END as 'Consumer Segment' FROM ( SELECT DISTINCT M.[Account Name Birth Date] as 'Birth Date', M.[Mailing Address State] as 'State', E.[ANSVIES2] as 'Income', E.[FICO] as 'FICO Score', DATEDIFF(DD,M.[Account Name Birth Date],GETDATE())/365 as [Age] FROM YourTableM M JOIN YourTableE E ON M.PrimaryKey = E.ForeignKey -- 替换成实际关联字段 ) AS TempData
另外提醒下:你原代码里漏掉了FROM子句和表关联逻辑,记得补上实际的表名和关联字段哦!
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

