一种更传统的方法可能如下:
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 |
+-------------+-----------+----------+-------+
这是一个奇怪的数据库设计。你可能想要正常化它。产品表应包含产品而不是订单明细。另一方面,订单详细信息应该是订单中的行,即订单中每个产品的一个记录。 –
@onedaywhen规范化的设计将允许产品的扩展而不需要进行结构改变。例如:(order_id,product_id,数量) - 我并不是说这是正确的结构,而是标准化的方法。 – Strawberry
@onedaywhen:你说得对; “正常化”是错误的术语。这个设计并没有违反正常的形式。所以更多关于正确的关系设计。产品是一个实体,与用户或订单相同,所以它不应该是表格中的列,而是行。一旦您需要添加用户,订单或产品,您将添加一行。但是,在所示的设计中,您必须为第四种产品添加一列,并相应地更改访问产品的查询。所以这不是关于正常形式所定义的规范化,而是关于一个结构良好的关系数据库。 –