使用SQL HAVING COUNT筛选含多个产品的订单查询问题
解决方法
你的问题出在GROUP BY子句包含了Products.ProductID。因为每个OrderDetails行对应一个唯一的ProductID(一个订单里的每个产品是一行记录),所以当你按Orders.OrderID, Customers.CustomerName, Products.ProductID分组时,每个分组里只会有一条记录——这就是为什么COUNT结果总是1。
要筛选出包含多个产品的订单,并展示这些订单下的客户姓名、OrderID和对应的ProductID,有两种常用方案:
方案1:子查询筛选符合条件的订单ID
先从OrderDetails里找出所有包含多个产品的OrderID,再关联其他表获取完整信息:
SELECT c.CustomerName, o.OrderID, p.ProductID FROM OrderDetails od INNER JOIN Orders o ON o.OrderID = od.OrderID INNER JOIN Customers c ON c.CustomerID = o.CustomerID INNER JOIN Products p ON p.ProductID = od.ProductID WHERE o.OrderID IN ( SELECT OrderID FROM OrderDetails GROUP BY OrderID HAVING COUNT(*) > 1 );
方案2:使用窗口函数(适合支持窗口函数的数据库)
通过窗口函数直接计算每个订单的总产品数,再过滤掉单产品订单:
SELECT CustomerName, OrderID, ProductID FROM ( SELECT c.CustomerName, o.OrderID, p.ProductID, COUNT(*) OVER (PARTITION BY o.OrderID) AS NumberOfProducts FROM OrderDetails od INNER JOIN Orders o ON o.OrderID = od.OrderID INNER JOIN Customers c ON c.CustomerID = o.CustomerID INNER JOIN Products p ON p.ProductID = od.ProductID ) AS OrderProductCounts WHERE NumberOfProducts > 1;
补充说明
- 方案1兼容性更强,适合所有支持子查询的数据库;
- 方案2更简洁,不需要额外的分组查询,直接在原查询基础上计算订单的产品总数;
- 你原来的HAVING条件写的
>2,如果是要排除仅含单个产品的订单,应该用>1(因为COUNT(*)是订单里的产品数量,>1表示至少2个产品)。
内容的提问来源于stack exchange,提问作者Jarod Rakoff
相关产品推荐
相关产品推荐

