SQL交叉连接(Cross Join)查询报错,求不用SUM和GROUP BY计算总和方案
解决存储过程的语法错误及总和计算需求
咱们先看你碰到的报错:Msg 156, Level 15, State 1, Procedure ServicesDetailedReport, Line 23 Incorrect syntax near the keyword 'as',这个问题根源在你的Cross join子查询里,写法有语法错误。
你原来的子查询是这么写的:
(Select SUM(inc.ServicePrice) as TotalCost from dbo.Invoices inc as TotalCost) t
这里的as TotalCost加在表别名inc后面完全不对——你已经给dbo.Invoices起了别名inc,不能再给它重复加别名,而且子查询的别名应该放在整个子查询的括号外面,不是内部表的后面。
修正后的存储过程代码
如果你的需求是在每条明细记录后面带上符合日期范围的所有发票的ServicePrice总和,我帮你修正了语法,还优化了日期比较的逻辑(别把日期转成varchar来比,直接转成date类型更高效,也不会踩格式坑):
ALTER PROCEDURE [dbo].[ServicesDetailedReport] @FromDate date = '01-Jun-2010', @ToDate date = null AS BEGIN -- 处理默认的ToDate值,直接转date类型更严谨 Set @ToDate = CASE WHEN @ToDate IS NULL THEN CAST(GETDATE() AS date) ELSE @ToDate END SELECT inv.InvoiceNo, inv.EntryDateTime, s.ServiceName, c.VehicleRegNo, inv.ServicePrice, c.CustomerName, inv.fk_BookingID, t.TotalCost -- 新增总和字段 FROM dbo.[Services] s INNER JOIN invoices inv ON inv.fk_ServiceID = s.ServiceID INNER JOIN customers c ON c.CustomerID = inv.fk_CustomerID -- 修正子查询的语法,同时在子查询里加上日期过滤,确保总和是符合范围的 CROSS JOIN ( SELECT SUM(inc.ServicePrice) AS TotalCost FROM dbo.Invoices inc WHERE CAST(inc.EntryDateTime AS date) BETWEEN @FromDate AND @ToDate ) AS t WHERE CAST(inv.EntryDateTime AS date) BETWEEN @FromDate AND @ToDate END
关于“不使用SUM和GROUP BY计算总和”的说明
你提到想不用SUM和GROUP BY来计算总和,这里得说清楚:
- 如果是不想用
GROUP BY,上面的写法已经满足——子查询里用SUM计算的是整个符合条件的数据集的总和,不需要GROUP BY - 如果是完全不想用SUM函数,那在SQL Server里没有更合适的替代方案,硬要做的话只能用循环逐条累加,但这样性能极差,完全没必要,SUM是计算总和最高效的方式
另外补充个小细节:原来的代码里Convert(varchar(11), getdate(), 106)转日期会得到字符串,直接转成date类型更严谨,避免后续比较出问题。
内容的提问来源于stack exchange,提问作者user9677867
相关产品推荐
相关产品推荐

