修复总余额查询:Northwind数据库国家间总余额SQL问题
嘿,我帮你把这个Northwind的SQL查询补全并理清楚逻辑哈~
首先,你的思路方向是对的:用排序国家名的方式避免重复的国家对(比如A-B和B-A只保留一组),通过CASE调整金额正负来计算双边余额。不过你的原语句缺少了关键的表关联——要计算国家间的贸易余额,我们需要把**买方国家(来自Customers表)和卖方国家(来自Suppliers表)**关联起来,毕竟订单是客户向供应商采购产品产生的。
下面是补全并优化后的完整查询:
SELECT -- 按字母顺序统一国家对的显示,确保每对只出现一次 CASE WHEN c.Country < s.Country THEN c.Country ELSE s.Country END AS CountryA, CASE WHEN c.Country < s.Country THEN s.Country ELSE c.Country END AS CountryB, -- 计算双边净余额:A向B采购的金额为正,B向A采购的金额为负,求和得到净额 SUM( CASE WHEN c.Country < s.Country THEN CONVERT(money, (od.UnitPrice * od.Quantity) * (1 - od.Discount)) ELSE -CONVERT(money, (od.UnitPrice * od.Quantity) * (1 - od.Discount)) END ) AS Balance FROM Orders o INNER JOIN [Order Details] od ON o.OrderID = od.OrderID INNER JOIN Customers c ON o.CustomerID = c.CustomerID INNER JOIN Products p ON od.ProductID = p.ProductID INNER JOIN Suppliers s ON p.SupplierID = s.SupplierID -- 可选:排除同一国家内部的交易,不需要的话可以删掉这行 WHERE c.Country <> s.Country GROUP BY CASE WHEN c.Country < s.Country THEN c.Country ELSE s.Country END, CASE WHEN c.Country < s.Country THEN s.Country ELSE c.Country END ORDER BY CountryA, CountryB;
关键逻辑说明:
- 表关联:通过
Orders→Customers拿到买方国家,Order Details→Products→Suppliers拿到卖方国家,把每笔交易的双边国家对应起来; - 去重国家对:用
CASE把国家按字母排序生成CountryA和CountryB,避免重复出现(A,B)和(B,A)两组相同的国家对; - 余额计算:当买方是
CountryA时,这笔交易是A向B的采购,金额计入余额为正;当买方是CountryB时,是B向A的采购,金额计入余额为负。最终的SUM结果就是两国间的净余额——正数表示A对B是贸易逆差(A买的比卖的多),负数则是顺差; - 分组排序:按排序后的国家对分组,确保每个组合只返回一行结果,最后按国家名排序方便查看。
如果你的需求里的“余额”定义和我理解的不同(比如是客户之间的其他余额),可以随时调整CASE里的正负逻辑哦~
内容的提问来源于stack exchange,提问作者DoktorAgon
相关产品推荐
相关产品推荐

