通过VBA-ADO实现MSSQL TRANSFORM/PIVOT销售报表显示全年月(含无销售)
我明白你的需求——要让报表显示所有指定年份的每一个月份,哪怕对应期间没有销售记录,对吧?你当前的查询因为直接基于源表的现有记录分组,所以缺失数据的月份会被漏掉,得通过生成一个完整的年月维度集来解决这个问题。
解决方案:生成完整年月维度集做左连接
要确保所有月份(1-12)和指定年份(2015-2025)都出现在报表里,我们需要先创建一个包含所有可能年月组合的「基础维度表」,再和你的销售数据左连接,这样即使没有销售记录,对应的行/列也会保留。
具体实现步骤
- 生成所有月份:用
VALUES子句创建1到12的月份列表 - 生成所有指定年份:同样用
VALUES子句列出你需要的2015-2025 - 交叉连接年月:得到所有年月的组合(12个月×11年=132条记录)
- 左连接销售数据:把这个维度集和你的
[Feuil$]表关联,匹配年份、月份和CODEFC - TRANSFORM/PIVOT聚合:基于左连接后的数据集做透视,保证所有年月都被包含
修改后的VBA SQL语句
把你的SQLq替换成下面的代码:
SQLq = "WITH AllMonths AS (" & _ "SELECT 1 AS MONTH UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL " & _ "SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL " & _ "SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL " & _ "SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12" & _ "), AllYears AS (" & _ "SELECT 2015 AS YEAR UNION ALL SELECT 2016 UNION ALL SELECT 2017 UNION ALL " & _ "SELECT 2018 UNION ALL SELECT 2019 UNION ALL SELECT 2020 UNION ALL " & _ "SELECT 2021 UNION ALL SELECT 2022 UNION ALL SELECT 2023 UNION ALL " & _ "SELECT 2024 UNION ALL SELECT 2025" & _ "), FullDateDim AS (" & _ "SELECT am.MONTH, ay.YEAR " & _ "FROM AllMonths am CROSS JOIN AllYears ay" & _ ") " & _ "TRANSFORM ISNULL(SUM(f.[PRICE]), 0) AS TotalSales " & _ "SELECT fd.MONTH " & _ "FROM FullDateDim fd " & _ "LEFT JOIN [Feuil$] f ON fd.MONTH = f.MONTH AND fd.YEAR = f.YEAR AND f.[CODEFC] = '" & CodeFC & "' " & _ "GROUP BY fd.MONTH " & _ "PIVOT fd.YEAR " & _ "IN(2015,2016,2017,2018,2019,2020,2021,2022,2023,2024,2025)"
关键说明
AllMonths和AllYears是CTE(公共表表达式),用来生成完整的月份和年份列表FullDateDim通过交叉连接得到所有年月的组合,确保没有遗漏LEFT JOIN保证即使[Feuil$]里没有对应年月的销售记录,维度集里的行依然保留ISNULL(SUM(f.[PRICE]), 0)把空值转换成0,让报表更美观(如果不需要0可以去掉,保留Null)- 因为我们基于
FullDateDim分组,所以所有12个月份都会出现在结果里,每个指定年份的列也会显示,没有销售的话值为0或Null
内容的提问来源于stack exchange,提问作者Proger_Cbsk
相关产品推荐
相关产品推荐

