SQL透视表查询报错:IN子句中使用SELECT关键字时语法错误
解决SQL Server PIVOT透视表的语法错误问题
你的错误核心在于SQL Server的PIVOT语法不允许在IN()子句中直接使用子查询来动态生成列名——这里必须明确指定要透视的列值,或者用动态SQL来构建这个列表。另外注意到你有个拼写错误:YearRecived应该是YearReceived(少了一个字母e),这个也得修正,不然会找不到对应列。
下面给你两种解决方案,根据你的需求选择:
方案1:静态列(已知固定的年份范围)
如果你的目标年份是固定的(比如2000到2023),可以直接把这些年份作为列名写在IN()里,示例代码:
SELECT * FROM ( SELECT Vendor_code, Vendor_name, Ord_date, SubTot, DateRecieved, CurrencyCode, YearReceived FROM [BL_CUSTOM PO HISTORY SUMMARY] ) AS S PIVOT ( SUM(S.SubTot) FOR S.YearReceived IN ([2000], [2001], [2002], [2003], [2004], [2005], [2006], [2007], [2008], [2009], [2010], [2011], [2012], [2013], [2014], [2015], [2016], [2017], [2018], [2019], [2020], [2021], [2022], [2023]) ) as pvt
这种方式简单直接,适合年份范围固定的场景。
方案2:动态SQL(年份动态变化)
如果你的年份是逐年新增的(比如每年都会有新的订单数据),就需要用动态SQL来自动生成列列表:
DECLARE @YearColumns NVARCHAR(MAX) DECLARE @PivotQuery NVARCHAR(MAX) -- 从年份表中生成带方括号的列名字符串,格式为[2000], [2001], ... SELECT @YearColumns = STUFF( (SELECT ', [' + CAST(year AS VARCHAR(10)) + ']' FROM [BL_CUSTOM YEAR COUNT] ORDER BY year FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '' ) -- 构造完整的透视查询语句 SET @PivotQuery = N' SELECT * FROM ( SELECT Vendor_code, Vendor_name, Ord_date, SubTot, DateRecieved, CurrencyCode, YearReceived FROM [BL_CUSTOM PO HISTORY SUMMARY] ) AS S PIVOT ( SUM(S.SubTot) FOR S.YearReceived IN (' + @YearColumns + ') ) as pvt' -- 执行动态生成的SQL EXEC sp_executesql @PivotQuery
这里用STUFF和FOR XML PATH拼接年份列名,给每个年份加上方括号(数字作为列名必须用方括号包裹),再通过sp_executesql安全执行动态SQL,能自动适配年份的变化。
最后提醒:检查[BL_CUSTOM YEAR COUNT]表中的年份是否和[BL_CUSTOM PO HISTORY SUMMARY]里的YearReceived值完全匹配,避免出现透视后无数据的情况。
内容的提问来源于stack exchange,提问作者Takudzwa Chinyani
相关产品推荐
相关产品推荐

