Reputation: 21
I'm trying to find the countries from which the number of orders is higher than the average. This is as far as I got. The problem is (see picture) that the count of orders for each country is off, as it should be different for everyone
SELECT avg(NumberOrders) as avg,
Customers.Country,
NumberOrders
FROM Customers,
(SELECT COUNT(Orders.OrderId) AS NumberOrders
FROM Customers JOIN
Orders ON Customers.CustomerID = Orders.CustomerID
GROUP BY Customers.Country) nested
GROUP BY Customers.Country
HAVING NumberOrders > avg;
Upvotes: 1
Views: 2979
Reputation: 60472
If your DBMS supports Windowed Aggregates (almost all besides MySQL & Access):
select *
from
(
SELECT Customers.Country,
COUNT(Orders.OrderId) AS NumberOrders, -- count per country
AVG(COUNT(Orders.OrderId)) OVER () AS avgOrders -- average count
FROM Customers
JOIN Orders
ON Customers.CustomerID = Orders.CustomerID
GROUP BY Customers.Country
) nested
WHERE NumberOrders > avgOrders
Edit:
For DBMSes not supporting Windowed Aggregates it's way more complicated:
SELECT Customers.Country,
COUNT(Orders.OrderId) AS NumberOrders -- count per country
FROM Customers
JOIN Orders
ON Customers.CustomerID = Orders.CustomerID
GROUP BY Customers.Country
HAVING COUNT(Orders.OrderId) >
( select avg(NumberOrders)
from
(
SELECT Customers.Country,
COUNT(Orders.OrderId) AS NumberOrders -- count per country
FROM Customers
JOIN Orders
ON Customers.CustomerID = Orders.CustomerID
GROUP BY Customers.Country
) AS dt
)
If the DBMS supports Common Table Expressions this can be simplified:
with cte as
(
SELECT Customers.Country,
COUNT(Orders.OrderId) AS NumberOrders -- count per country
FROM Customers
JOIN Orders
ON Customers.CustomerID = Orders.CustomerID
GROUP BY Customers.Country
)
select *
from cte
WHERE NumberOrders >
(
select avg(NumberOrders) from cte
)
Upvotes: 2