在WHERE子句中新增变量及CROSS APPLY使用失败的SQL问题求助
解决方案
你的问题核心是SQL执行顺序导致SELECT里的别名无法在JOIN/WHERE中直接使用——数据库会先处理FROM/JOIN逻辑,再执行SELECT的字段计算,所以mmm这个别名在JOIN阶段还没生成,自然无法匹配。
针对你的需求,提供两种可行方案:
方案1:直接在JOIN条件中重复日期转换表达式
把SELECT里生成mmm的逻辑直接复制到JOIN的ON子句里,这样数据库能直接计算并匹配ck.Lookup.date1:
SELECT a.bim, a.cim, b.Block, DATENAME(dw, a.start_date) + ', ' + CONVERT(varchar(20), a.start_date, 107) AS mmm FROM CK.SCHEDULE a LEFT JOIN ck.Lookup b ON b.date1 = DATENAME(dw, a.start_date) + ', ' + CONVERT(varchar(20), a.start_date, 107) WHERE a.bim = '2024'
方案2:用CROSS APPLY预先计算日期格式(更简洁,避免重复代码)
如果不想重复写转换逻辑,可以用CROSS APPLY把mmm的计算提前,之后在JOIN和WHERE里直接引用这个预计算的字段:
SELECT a.bim, a.cim, b.Block, calc.mmm FROM CK.SCHEDULE a CROSS APPLY ( SELECT DATENAME(dw, a.start_date) + ', ' + CONVERT(varchar(20), a.start_date, 107) AS mmm ) AS calc LEFT JOIN ck.Lookup b ON b.date1 = calc.mmm WHERE a.bim = '2024'
额外优化建议
如果ck.Lookup.date1是字符串类型,上面的方案完全适用;如果它本质是日期类型,建议反过来转换date1为datetime来匹配a.start_date,这样能避免全表扫描字符串匹配,性能更好:
SELECT a.bim, a.cim, b.Block, DATENAME(dw, a.start_date) + ', ' + CONVERT(varchar(20), a.start_date, 107) AS mmm FROM CK.SCHEDULE a LEFT JOIN ck.Lookup b ON CONVERT(datetime, b.date1, 107) = CAST(a.start_date AS date) WHERE a.bim = '2024'
内容的提问来源于stack exchange,提问作者user22168985
相关产品推荐
相关产品推荐

