2014-09-28 97 views
0

问:对于每个客户列表,CustomerID和所下的订单总数。三个表上的SQL查询返回一个综合答案

我相信,我可以用这三个表

Customer_T        Order_T     OrderLine_T 
+------+------+------+- +---------+-----------+-------+ +---------+-----------------+ 
|CustID| CNAME | Addr | | OrderID | OrderDate |CustID | |OrderID | OrderedQuantity | 
+------+------+------+ +-------+----+--------+-------+ +---------+-----------------+ 

我试过几个查询执行这个查询,这是因为它不是在一个聚合包含返回错误Customer_T.CustomerID无效我最新的迭代功能或按分组划分。

SELECT 
    Customer_T.CustomerID, Order_T.OrderID 
FROM 
    Customer_T, Order_T, OrderLine_T 
WHERE 
    Order_T.CustomerID=Customer_T.CustomerID 
    AND Order_T.OrderID=OrderLine_T.OrderID 
ORDER BY 
    COUNT(OrderLine_T.OrderedQuantity) 

我不知道哪里去了这里...我应该使用连接运算符的东西?

编辑:我应该提到,需要从Customer_T表中拉出额外的CustID是B/C有客户谁没有购买任何东西,并没有包括在订单表(每个客户)。

+3

[不良习惯踢:使用旧样式的JOIN(HTTP:// sqlblog。com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using-old-style-joins.aspx) - 旧式*逗号分隔的表*样式列表被替换为*正确*在ANSI ANSI ** 92 ** SQL标准(**超过20年**前)中使用ANSI'JOIN'语法,并且不鼓励使用它 – 2014-09-28 07:18:07

+0

是的,您应该尝试使用JOIN。在你的情况下使用连接实现结果相当容易。 – 2014-09-28 07:19:06

+0

好的,我还没有加入。我不太清楚如何考虑这样的查询。有人会提供一些伪代码吗? – 2014-09-28 07:26:06

回答

0

对于每个客户列表中的客户ID,并放置

此订单总数只需要2个表(客户和订单)

SELECT 
     Customer_T.CustomerID 
    , COUNT(Order_T.OrderID) orders_per_customer 
FROM Customer_T 
LEFT OUTER JOIN Order_T ON Customer_T.CustomerID = Order_T.CustomerID 
GROUP BY 
     Customer_T.CustomerID 
ORDER BY 
     Customer_T.CustomerID 
; 

注意使用LEFT OUTER JOIN,这个连接类型允许,即使他们还没有下订单要返回在Customer_T所有记录。我建议您访问here for a visual representation of SQL joins

您可以添加第三张表以获取更多信息,但您需要注意不要夸大订单数量,因为每个订单的订单项意味着一对多关系(许多订单项单一订单)。你可以通过引入COUNT(DISTINCT ...)

SELECT 
     Customer_T.CNAME 
    , Customer_T.CustomerID 
    , COUNT(DISTINCT Order_T.OrderID) orders_per_customer 
    , SUM(OrderLine_T.OrderedQuantity) sum_of_quantity 
FROM Customer_T 
LEFT OUTER JOIN Order_T ON Customer_T.CustomerID = Order_T.CustomerID 
LEFT OUTER JOIN OrderLine_T ON Order_T.OrderID = OrderLine_T.OrderID 
GROUP BY 
     Customer_T.CNAME 
    , Customer_T.CustomerID 
ORDER BY 
     Customer_T.CNAME 
    , Customer_T.CustomerID 
; 

注量的总和不是一个非常有意义的指标做到这一点,它的存在只是作为方法的演示。

+0

非常感谢您的明确解释。这非常有帮助。 – 2014-09-28 18:45:47

0

这可能会帮助你得到正确的答案。

SELECT ord.CustID, count(ord.CustID) AS OrderCount, cust.CNAMR 
FROM Customer_T cust JOIN Order_T ord 
    ON (ord.CustomerID=cust.CustomerID) 
    JOIN OrderLine_T ordLine 
    ON (ord.OrderID=ordLine.OrderID) 
GROUP BY ord.CustID ORDER BY OrderCount Desc 

但在这里获取订单数量会比较棘手。

+0

这并不完全正确的答案,但它是一个很好的起点。我是否正确地假设在Customer_T cust中,cust是别名? – 2014-09-28 07:34:49

+0

雅我想我必须删除组并重新构建一点。是cust是一个别名。 – 2014-09-28 07:35:58

+0

没有什么。仍然没有正确返回。 – 2014-09-28 07:52:13

0

这是你所需要的。

SELECT C.CustID, COUNT(OL.OrderedQuantity) 
FROM Customer_T C 
    JOIN Order_T O ON(O.OrderID=C.CustID) 
    JOIN OrderLine_T OL ON(O.OrderID = OL.OrderID) 
GROUP BY C.CustID 
+0

接近,在第3行O.OrderID应该是O.CustID。而且,虽然我认为它正在返回正确的值,但它没有返回具有0次购买的客户ID – 2014-09-28 07:50:41

0

既然你只需要“......列出客户ID和下订单的总数”你不需要加入任何其他表,所有的信息在Order_T表可用:

SELECT CustID, COUNT(OrderID) AS OrderCount 
FROM Order_T 
GROUP BY CustID 

如果你想显示客户的名字,那么你将需要连接的表。

+0

我是sry。我将编辑帖子。有些客户没有购买任何东西,因此需要从包含客户ID的相邻表中返回他们的信息。 – 2014-09-28 07:53:27

0

试试这个

SELECT 
    C.CustID, 
    SUM(CASE O.OrderID WHEN NULL THEN 0 ELSE 1 END) AS NumberOfOrdersPlaced 
FROM Customer_T C 
    LEFT JOIN Order_T O ON (O.CustID = C.CustID) 
GROUP BY C.CustID 

上面的查询将返回放在每个客户的订单数。如果客户没有的订货呢,然后NumberOfOrdersPlaced列的值将为0。