2016-10-25 2 views
0

Таблица - КлиентыSQL Inner Присоединиться к группе По

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! Обычно он включает выбранные столбцы, которые не являются аргументами для функции set.

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 Кеттнер, вы должны рассмотреть вопрос нормализации вашего дизайна таблицы.

+0

ThorstenKettner и Strawberry оба утверждали, что он не был полностью нормализован, но когда его оспаривали, нормальная форма, которая нарушается. Как насчет тебя? – onedaywhen

+0

@oneday когда да, нормализованное не может быть здесь. IMO Я думаю, что продукты должны быть данными, а не фиксированными в столбце в таблице Products, и у нас будет таблица '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 | 
+-------------+-----------+----------+-------+ 
Смежные вопросы