SeagullWardy
SeagullWardy

Reputation: 187

SQL Count Not working over multiple tables

I am teaching myself SQL and have been using the W3Schools website. On their website they have a dummy database that they use to demonstrate different things. You can also use this to try things out your self. Their TryIt editor can be found at https://www.w3schools.com/sql/trysql.asp?filename=trysql_select_distinct

After working through their examples I have been inventing questions and trying to answer them. However, I have come across something that does not appear to be working and I wanted to know if it was an error in my code, error on the W3Schools site or just a limitation of SQL.

When I run the following code it works as expected and returns the number of orders for each customer.

SELECT c.CustomerName, COUNT(o.OrderID) AS NumberOfOrders
FROM Customers AS C
LEFT JOIN Orders AS o ON c.CustomerID = o.CustomerID
GROUP BY c.CustomerName

I then decided to try and extend the query to also give the total amount of those orders using the following code.

SELECT c.CustomerName, COUNT(o.OrderID) AS NumberOfOrders, SUM(od.Quantity * p.price) AS TotalOfOrders
FROM (((Customers AS C
LEFT JOIN Orders AS o ON c.CustomerID = o.CustomerID)
LEFT JOIN OrderDetails AS od ON o.OrderID = od.OrderID)
LEFT JOIN Products AS p ON od.ProductID = p.ProductID)

Now when I run the code count on the OrderID is not working. For example for customer Ana Trujillo Emparedados y helados (CustomerID 2) it returns 2 instead of 1. This is the number of items that their one order contained.

Am I missing something obvious?

Upvotes: 1

Views: 95

Answers (5)

pwain
pwain

Reputation: 279

Have a look at this statement

SELECT c.CustomerID,c.CustomerName, o.OrderId
FROM (((Customers AS C
LEFT JOIN Orders AS o ON c.CustomerID = o.CustomerID)
LEFT JOIN OrderDetails AS od ON o.OrderID = od.OrderID)
 )

this shows you that your left join shows the orderId twice. And the count operator counts it twice.

You need to count distinct values

This should be correct:

SELECT c.CustomerID,c.CustomerName, COUNT(DISTINCT o.OrderID) AS NumberOfOrders, SUM(od.Quantity * p.price) AS TotalOfOrders
FROM (((Customers AS C
LEFT JOIN Orders AS o ON c.CustomerID = o.CustomerID)
LEFT JOIN OrderDetails AS od ON o.OrderID = od.OrderID)
LEFT JOIN Products AS p ON od.ProductID = p.ProductID)
GROUP by c.CustomerID,c.CustomerName

Upvotes: 1

SeagullWardy
SeagullWardy

Reputation: 187

Seems to work when I amend the SELECT statement to

SELECT c.CustomerName, COUNT (DISTINCT o.OrderID) AS NumberOfOrders, SUM(od.Quantity * p.Price) AS TotalOfOrders

Thanks Colour Dalnet for your suggestion.

Upvotes: 1

Pratik Vaghasiya
Pratik Vaghasiya

Reputation: 46

In w3school you can use limited join condition So use your private server :)

Upvotes: 1

George Lords of Castle
George Lords of Castle

Reputation: 1695

First of all, in your second query the group by clause is missing. You are doing an error called "double counting". For the case you are naming (Trujillo Emparedados y helados), the count is right because there are 2 details related the only order related to the customer. So now you are not counting the orders, but you are counting the order details. To obtain the "1" you want you have to fix the query with a "distinct" in this way:

SELECT c.CustomerName, COUNT(distinct o.OrderID) AS NumberOfOrders, 
SUM(od.Quantity * p.price) AS TotalOfOrders
FROM (((Customers AS C
LEFT JOIN Orders AS o ON c.CustomerID = o.CustomerID)
LEFT JOIN OrderDetails AS od ON o.OrderID = od.OrderID)
LEFT JOIN Products AS p ON od.ProductID = p.ProductID)
group by c.CustomerName

Upvotes: 1

Jun Rikson
Jun Rikson

Reputation: 1884

There is nothing wrong with your query and result,

It is because OrderDetails.ProductID 69 and 70 in same orderID (10308)

You can get full result with select * :

SELECT *
FROM (((Customers AS C
LEFT JOIN Orders AS o ON c.CustomerID = o.CustomerID)
LEFT JOIN OrderDetails AS od ON o.OrderID = od.OrderID)
LEFT JOIN Products AS p ON od.ProductID = p.ProductID)
WHERE c.CustomerID = 2

Upvotes: 1

Related Questions