2016-10-25 428 views
0

表 - 客户SQL内加入集团通过

id FirstName LastName 
23 James  Smith  
24 Tom  Raven 
25 Bob  King 

表 - 订单

id CustomerID 
30 23 
31 24 
32 23 
33 25 

表 - 产品

OrderID Product1 Product2 Product3 
30  1  0  0 
31  2  0  0 
32  0  1  1 
33  2  1  0 

我要计数产品的总数为每个客户所以答案是:

CustomerID FirstName LastName Total 
23   James  Smith 3 
24   Tom  Raven 2 
25   Bob  King  3 

到目前为止,我已经得到了SQL查询:

SELECT Customers.id, Orders.id, 
FROM Customers 
INNER JOIN Orders ON Customers.id = Orders.CustomerID 
INNER JOIN Products ON Orders.id = Products.OrderID 

不知道如何虽然计数的产品。

任何帮助将不胜感激。

+2

这是一个奇怪的数据库设计。你可能想要正常化它。产品表应包含产品而不是订单明细。另一方面,订单详细信息应该是订单中的行,即订单中每个产品的一个记录。 –

+0

@onedaywhen规范化的设计将允许产品的扩展而不需要进行结构改变。例如:(order_id,product_id,数量) - 我并不是说这是正确的结构,而是标准化的方法。 – Strawberry

+0

@onedaywhen:你说得对; “正常化”是错误的术语。这个设计并没有违反正常的形式。所以更多关于正确的关系设计。产品是一个实体,与用户或订单相同,所以它不应该是表格中的列,而是行。一旦您需要添加用户,订单或产品,您将添加一行。但是,在所示的设计中,您必须为第四种产品添加一列,并相应地更改访问产品的查询。所以这不是关于正常形式所定义的规范化,而是关于一个结构良好的关系数据库。 –

回答

0
SELECT Customers.id, Customers.firstname, Customers.lastname,count(*) as total FROM Customers 
INNER JOIN Orders 
ON Customers.id=Orders.CustomerID 
INNER JOIN Products 
ON Orders.id=Products.OrderID 
group by Customers.id,Customers.firstname, Customers.lastname 
0

添加GROUP BY子句!通常它包含选定的列,它们不是设置函数的参数。

SELECT O.CustomerID, C.FirstName, C.LastName, count(*) as Total 
FROM Customers C 
INNER JOIN Orders O ON C.id = O.CustomerID 
INNER JOIN Products P ON O.id = P.OrderID 
GROUP BY O.CustomerID, C.FirstName, C.LastName 

PS。现在使用表别名来保存一些输入。

1
select c.id as CustomerID 
    ,(sum(p.Product1) + sum(p.Product2) + sum(p.Product3)) as ProductCount 
from Customers c 
inner join Orders o on c.id = o.CustomerID 
inner join Products p on o.id = p.OrderID 
group by c.id 
1

你可以使用

SELECT c.id as CustomerID, c.firstname, c.lastname, 
    sum(p.Product1 + p.Product2 + p.Product3) as total 
FROM Customers c 
INNER JOIN Orders o 
ON c.id=o.CustomerID 
INNER JOIN Products p 
ON o.id=p.OrderID 
group by c.id,c.firstname, c.lastname; 

而作为@Thorsten KETTNER的评论,你应该考虑你的正常化表的设计。

+0

ThorstenKettner和Strawberry都声称它没有完全标准化,但是当挑战时,一种正在被侵犯的正常形式。你呢? – onedaywhen

+0

@onedaywhen是的,标准化可能不是这里的词。国际海事组织我认为产品应该是数据,而不是固定在表产品栏中,我们将有'orders_product(id,productid,numberOrdered)'表。这个词怎么在这里?重新设计表格? –

0
SELECT DISTINCT CustomerID, FirstName, LastName, Total 
    FROM (SELECT id AS CustomerID, FirstName, LastName FROM Customers) AS c 
     NATURAL JOIN 
     (SELECT id AS OrderID, CustomerID FROM Orders) AS o 
     NATURAL JOIN 
     (SELECT OrderID, SUM(Product1 + Product2 + Product3) AS Total 
      FROM Products 
     GROUP 
      BY OrderID) AS p; 
0

一种更传统的方法可能如下:

DROP TABLE IF EXISTS customers; 

CREATE TABLE customers 
(customer_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY 
,firstname VARCHAR(20) NOT NULL 
,lastname VARCHAR(20) NOT NULL 
); 

INSERT INTO customers VALUES 
(23,'James','Smith'), 
(24,'Tom','Raven'), 
(25,'Bob','King'); 

DROP TABLE IF EXISTS orders; 

CREATE TABLE orders 
(order_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY 
,customer_id INT NOT NULL 
); 

INSERT INTO orders VALUES 
(30 ,23), 
(31 ,24), 
(32 ,23), 
(33 ,25); 

DROP TABLE IF EXISTS order_detail; 

CREATE TABLE order_detail 
(order_id INT NOT NULL 
,product_id INT NOT NULL 
,quantity INT NOT NULL 
,PRIMARY KEY(order_id,product_id) 
); 

INSERT INTO order_detail VALUES 
(30 ,1 ,1), 
(31 ,1 ,2), 
(33 ,1 ,2), 
(32 ,2 ,1), 
(33 ,2 ,1), 
(32 ,3 ,1); 

SELECT c.* 
    , SUM(od.quantity) total 
    FROM customers c 
    JOIN orders o 
    ON o.customer_id = c.customer_id 
    JOIN order_detail od 
    ON od.order_id = o.order_id 
GROUP 
    BY c.customer_id; 

+-------------+-----------+----------+-------+ 
| customer_id | firstname | lastname | total | 
+-------------+-----------+----------+-------+ 
|   23 | James  | Smith |  3 | 
|   24 | Tom  | Raven |  2 | 
|   25 | Bob  | King  |  3 | 
+-------------+-----------+----------+-------+