将Access PIVOT查询转换为SQL Server查询的报错排查与正确写法咨询
解决SQL Server PIVOT转换的报错问题及正确写法
首先拆解你遇到报错的核心原因:
- 你的子查询已经对
QUANTIDADE做了SUM聚合并命名为Total,子查询结果集里不再存在QUANTIDADE字段,所以PIVOT里引用Sum(QUANTIDADE)会提示列不存在。 - PIVOT的
FOR子句逻辑错误:你需要把COD_DIA的不同值转成列,因此应该写FOR COD_DIA而非FOR QUANTIDADE。 - 原Access的WHERE子句存在语法逻辑混乱,
FAMILIA='TESTE1' or FAMILIA='TESTE2' In (...)的写法不符合预期,应该是筛选FAMILIA为TESTE1或TESTE2,同时关联子查询的月份条件。
静态PIVOT写法(适用于COD_DIA值固定的场景,比如1-4)
如果COD_DIA的取值是确定的(比如固定1到4),可以用静态PIVOT实现:
SELECT SUPERVISOR, Total, [1], [2], [3], [4] -- 明确列出需要转成列的COD_DIA值 FROM ( SELECT SUPERVISOR, COORDENADOR, COD_DIA, QUANTIDADE, -- 用窗口函数计算每个Supervisor的总数量,避免提前聚合丢失原始QUANTIDADE字段 SUM(QUANTIDADE) OVER (PARTITION BY SUPERVISOR, COORDENADOR) AS Total FROM REPORTING WHERE (FAMILIA = 'TESTE1' OR FAMILIA = 'TESTE2') AND CODMES_REPORT IN (SELECT MaxOfCODMES_REPORT FROM [00 - Max Data Report ESALES]) ) t PIVOT ( SUM(QUANTIDADE) -- 对原始QUANTIDADE求和,对应Access中的SumOfQUANTIDADE FOR COD_DIA IN ([1], [2], [3], [4]) -- 指定要转成列的COD_DIA值 ) AS p ORDER BY COORDENADOR;
动态PIVOT写法(适用于COD_DIA值不固定的场景,比如月末31列)
由于COD_DIA的数量会随日期变化(比如月末会生成31列),静态写法无法适配,需要用动态SQL自动拼接列名:
DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX); -- 动态获取所有符合条件的COD_DIA值,拼接成[1],[2],...的格式 SELECT @cols = STUFF((SELECT ',' + QUOTENAME(COD_DIA) FROM (SELECT DISTINCT COD_DIA FROM REPORTING WHERE (FAMILIA = 'TESTE1' OR FAMILIA = 'TESTE2') AND CODMES_REPORT IN (SELECT MaxOfCODMES_REPORT FROM [00 - Max Data Report ESALES])) AS diaList ORDER BY COD_DIA FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,''); -- 拼接完整的查询语句 SET @query = ' SELECT SUPERVISOR, Total, ' + @cols + ' FROM ( SELECT SUPERVISOR, COORDENADOR, COD_DIA, QUANTIDADE, SUM(QUANTIDADE) OVER (PARTITION BY SUPERVISOR, COORDENADOR) AS Total FROM REPORTING WHERE (FAMILIA = ''TESTE1'' OR FAMILIA = ''TESTE2'') AND CODMES_REPORT IN (SELECT MaxOfCODMES_REPORT FROM [00 - Max Data Report ESALES]) ) t PIVOT ( SUM(QUANTIDADE) FOR COD_DIA IN (' + @cols + ') ) AS p ORDER BY COORDENADOR'; -- 执行动态SQL EXEC sp_executesql @query;
额外说明
- 原Access查询的
GROUP BY COORDENADOR, SUPERVISOR逻辑,我们用窗口函数SUM(QUANTIDADE) OVER (PARTITION BY SUPERVISOR, COORDENADOR)实现,既保留了原始QUANTIDADE字段用于PIVOT聚合,又能得到每个Supervisor的Total列。 - 已修正WHERE子句的逻辑,如果你的原始需求和这个逻辑有出入,可以根据实际业务调整筛选条件。
内容的提问来源于stack exchange,提问作者rafamaniac
相关产品推荐
相关产品推荐

