含双内连接的SQL查询添加GROUP BY报错问题求助
解决GROUP BY报错Msg 8120的问题
咱们来搞定这个GROUP BY的报错问题!首先得明白为什么会出现这个错误:
错误原因分析
SQL Server对GROUP BY有严格的规则:SELECT子句里所有没有用聚合函数(比如SUM、MAX、MIN)包裹的列,必须全部出现在GROUP BY子句中。你只把[b].[FullName]加入了GROUP BY,但SELECT里的[InvNo]、[AdCaption]、[NetAmt]等列既不在GROUP BY里,也没有用聚合函数处理,数据库不知道怎么对这些列进行分组计算,所以就抛出了Msg 8120的错误。
接下来根据你的实际需求,给你两种解决方案:
方案一:保留每条订单记录,合并对应日期(最接近你原查询的意图)
你的原查询因为关联了DBTrans(一对多关系)导致订单记录重复,其实不需要GROUP BY,改用CROSS APPLY预计算每个订单对应的日期拼接,就能避免重复行,同时正常展示所有订单详情:
SELECT [b].[FullName], DateList.ins_Dates, [uk].[InvNo], [uk].[AdCaption], CONCAT([uk].[AdCM], 'x', [uk].[AdCOL]) AS [SIZE], [uk].[NetAmt], [uk].[RecievedAmount], [uk].[NetAmt] - [uk].[RecievedAmount] AS [O_S] FROM [DailyBooking] [uk] INNER JOIN [Publication] [b] ON [uk].[AdPub] = [b].[ID] -- 预计算每个DailyBooking对应的所有日期拼接 CROSS APPLY ( SELECT STUFF( ( SELECT ','+CONVERT(VARCHAR(30), [t].[pdate], 120) FROM [DBTrans] [t] WHERE [t].[dbID] = [uk].[ID] FOR XML PATH('') ), 1, 1, '') AS ins_Dates ) AS DateList WHERE [b].[FullName] LIKE '%a%';
方案二:按出版物名称(FullName)分组汇总
如果你确实需要按[b].[FullName]分组,合并该出版物下的所有日期,同时对订单数据进行聚合统计,那就要把所有非聚合列要么加入GROUP BY,要么用聚合函数处理(聚合函数要根据你的业务逻辑选择,比如MAX、SUM等):
SELECT [b].[FullName], -- 合并该出版物下所有关联的DBTrans日期 STUFF( ( SELECT ','+CONVERT(VARCHAR(30), [t].[pdate], 120) FROM [DBTrans] [t] INNER JOIN [DailyBooking] [uk_t] ON [t].[dbID] = [uk_t].[ID] WHERE [uk_t].[AdPub] = [b].[ID] FOR XML PATH('') ), 1, 1, '') AS [ins_Dates], MAX([uk].[InvNo]) AS [InvNo], -- 示例:取该出版物下的最大订单号 MAX([uk].[AdCaption]) AS [AdCaption], -- 示例:取该出版物下的首个/最大广告标题 MAX(CONCAT([uk].[AdCM], 'x', [uk].[AdCOL])) AS [SIZE], -- 示例:取该出版物下的最大广告尺寸 SUM([uk].[NetAmt]) AS [NetAmt], -- 示例:汇总该出版物下的总订单金额 SUM([uk].[RecievedAmount]) AS [RecievedAmount], -- 示例:汇总该出版物下的已收金额 SUM([uk].[NetAmt]) - SUM([uk].[RecievedAmount]) AS [O_S] FROM [DailyBooking] [uk] INNER JOIN [Publication] [b] ON [uk].[AdPub] = [b].[ID] WHERE [b].[FullName] LIKE '%a%' GROUP BY [b].[FullName];
方案选择建议
- 如果你需要保留每条
DailyBooking的详细信息,只是合并对应的多个日期,选方案一,这能避免原查询的重复行问题,同时符合你的初始需求。 - 如果你需要按出版物名称做汇总统计,比如看每个出版物的总订单金额、所有关联日期,选方案二,记得根据实际业务调整聚合函数(比如把MAX改成MIN,或者SUM改成AVG等)。
内容的提问来源于stack exchange,提问作者Syed Muhammad Munis Ali
相关产品推荐
相关产品推荐

