0

I'm practicing writing SQL queries, I just wanted to check that my answer would give me the desired result.

I'm given a few tables of a database, I need to retrieve "the customer IDs of customers that have ordered any product from a supplier based in Canberra"

The tables:

  • Suppliers (SupplierID, CompanyName, ContactName,ContactTitle, Address, City, Region, PostalCode, Country, Phone, Fax, HomePage)
  • Products (ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued)
  • OrderDetails(OrderID, ProductID, UnitPrice, Quantity, Discount)
  • Orders (OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate, ShippedDate, ShipVia, Freight, ShipName, ShipAddress, ShipCity, ShipRegion, ShipPostalCode, ShipCountry)
  • Customers (CustomerID, CompanyName, ContactName, ContactTitle, Address, City, Region, PostalCode, Country, Phone, Fax)
  • Employees (EmployeeID, LastName, FirstName, Title, TitleOfCourtesy, BirthDate, HireDate, Address, City, Region, PostalCode, Country, HomePhone, Extension, Photo, Notes, ReportsTo, PhotoPath)
  • Shippers (ShipperID, CompanyName, Phone)

The SQL query I've written:

SELECT Customer.CustomerID
FROM Customers, Orders
WHERE (Customers.CustomerID = Orders.CustomerID)
  AND (Orders.ProductID IN (SELECT Products.ProductID
                            FROM Suppliers, Products
                            WHERE (Products.SupplierID = Suppliers.SupplierID)
  AND (Suppliers.City = 'Canberra'))

The query should retrieve a list of customer numbers that match customers that have ever ordered a product that a Canberra supplier has made.

2
  • thanks M. R., wasn't sure how to format the post
    – Dylan1993
    Commented May 12, 2019 at 13:13
  • 1
    Bad habits to kick : using old-style JOINs - that old-style comma-separated list of tables style was replaced with the proper ANSI JOIN syntax in the ANSI-92 SQL Standard (more than 25 years ago) and its use is discouraged
    – marc_s
    Commented May 12, 2019 at 13:39

3 Answers 3

1

Do it with proper joins and aliases for the tables:

SELECT DISTINCT c.CustomerID
FROM Customers AS c 
INNER JOIN Orders AS o ON c.CustomerID = o.CustomerID
INNER JOIN Products AS p ON o.ProductID = p.ProductID 
INNER JOIN Suppliers AS s ON p.SupplierID = s.SupplierID
WHERE s.City = 'Canberra'
2
  • When do you use sub queries instead of inner joins?
    – Dylan1993
    Commented May 12, 2019 at 14:04
  • Subqueries and join are 2 different things. You don't need subqueries in your case. You only need to join tables and not specific portions of the tables. After the joins you set conditions to restrict the rows like: WHERE s.City = 'Canberra'
    – forpas
    Commented May 12, 2019 at 14:08
0

That looks fine. If you just want the number of customers, you could select only the COUNT(Customer.CustomerID).

1
  • sorry, I don't want to count the number of customers, I meant i want to list the IDs of customers that match the criteria. Would this subquery work?
    – Dylan1993
    Commented May 12, 2019 at 13:11
0

I would change the SELECT to SELECT DISTINCT : otherwise you will get a CustomerID row for every order that matches the products condition; which can be multiple (orders) per customer.

While I would write the query exactly as you did (with the added DISTINCT), you might consider the following example to be more readable:

SELECT
    Customer.CustomerID
FROM
    Customers, 
    Orders,
    Products,
    Suppliers
WHERE
    Customers.CustomerID = Orders.CustomerID AND
    Orders.ProductID = Products.ProductID AND
    Products.SupplierID = Suppliers.SupplierID AND
    Suppliers.City = 'Canberra'
GROUP BY 
    Customer.CustomerID
1
  • Ah of course. Distinct would be a very good idea. Thanks alot
    – Dylan1993
    Commented May 12, 2019 at 14:04

Not the answer you're looking for? Browse other questions tagged or ask your own question.