Multiple table queries

Physical modelThe power of SQL is apparent with queries involving data from multiple tables. This topic has three parts:

  • NULL values - a short aside on the non-intuitive behaviour of NULLs in queries
  • Multiple table queries - writing SELECT queries that retrieve data from more than one table
  • Handling DATEs - another short aside on Oracle's handling of DATEs

NULL values

Care is needed when retrieving rows in tables that may contain NULL values. As the reading shows, NULL has some unique characteristics when compared to other values.

Have a go: NULL in queries

 

Multiple table queries

Textbook reading
Ch 7 pp 323-332

The following reading from your textbook Multiple Table Queries shows how to join tables together to retrieve information from multiple tables.

Remember
There should be one join condition within the WHERE clause for each pair of tables being joined. Thus, if two tables are to be combined, one condition would be necessary, but if three tables (A, B and C) are to be combined, then two conditions would be necessary because there are two pairs of tables (A-B and B-C), and so forth.

A summary of the different types of Joins is provided opposite .

Have a go: Cross Joins

Understanding the order in which the different parts of a SELECT query are executed will help you write more complicated queries and work out why other queries don't work as you expected.

Have a go: processing order

 

Handling DATEs

Oracle's treatment of DATEs does not follow the SQL standard. This short reading explains how DATEs are implemented and how to use them. If you wish, you can skip this section until you come to the queries below that use DATEs.

 

Getting your hands dirty

Invoice database 1

Now try the following queries on the INVOICE database.

These activities relate to the PowerPoint Presentation “Multi-table queries” refer to “get your hands dirty”

1. Find the customer details for invoice 12Your query should return

CUSTABN CUSTNAME CUSTSUBURB CUSTNAME CUSTSTATE CUSTPOSTCODE
17652258874 Adams Tractors 65 Earl St Terara NSW 2540

 

2. Find the names of all customers who brought an item with Tube in its description Your query should return

CUSTNAME
Victor Panels
Astian Court Holdings

3. Find the customers who live in NSW or Qld who brought Screens Your query should return

CUSTNAME
Victor Panels
Mellow Yellow Lighting
Australian Drums
Australian Drums

4. Find the number of Screens brought by customers in NSW and Qld Your query should return

CUSTNAME SUM(QUANTITY)
Australian Drums 10
Victor Panels 5
Mellow Yellow Lighting 4


Check (invoice database 1)

The Answers to these will be available in Week Tasks multiple table queries.
The specific day is mentioned in announcements.

 

INVOICE databaseInvoice database 2

Now try the following queries on the INVOICE database.

1. For each customer that has an invoice, what is the customer's name and invoice number? Your query should return

2. Show which customers have received an invoice and sort by name. Remove any duplicates. Your query should return

3. Show the customer ABN and name and list all of the items as well as a quantity, description and price for invoice number 21. Your query should return

4. Find the number of invoices for each customer name. Your query should return

5. Find the customer name, invoice number and value of each invoice. Your query should return

6. Find the number of invoices for each customer whose name starts with A to E. Try writing this query two ways: once without the HAVING clause, once with the HAVING clause. Your query should return

7. Find all the customers who have more than one invoice. Could you write this query without the HAVING clause? Your query should return

8. For each customer, find out how much their invoices are worth. Your query should return

9. Find all the customers who have more than one invoice and have the letter t or T in their name. Your query should return

10. Find all customers who have invoices dated before August 2005. Your query should return

11. Find the customer name, invoice no and date (format MON 22 AUGUST 2005) for invoices in August 2005. Your query should return

INVOICE databaseCheck (invoice database 2)

1. For each customer that has an invoice, what is the customer's name and invoice number? Your query should return

View the answer

SELECT CUSTOMER.CustABN, CustName, InvoiceNo
FROM CUSTOMER, INVOICE
WHERE CUSTOMER.CustABN = INVOICE.CustABN;

Notice in the query we had to declare which table we wanted the CustABN to come from, and in the WHERE statement declare the fields in both tables.

This is because there is ambiguity, as CustABN exists in both tables. We must specify which table SQL Plus should pick the field from. This is only a problem when we have the same field names (notice we did not worry about CustName and InvoiceNo).

Remember that we can also uses aliases for our field names. We can also do the same for our tables. If the above query was a more involved one we would soon get sick of typing CUSTOMER.Something or INVOICE.Something.

We can make life easier with something like this:

SELECT CUSTOMER.CustABN AS ABN, CustName AS Name, InvoiceNo AS "Invoice Number"
FROM CUSTOMER c, INVOICE i
WHERE c.CustABN = i.CustABN;

This returns the same but with meaningful column headers. Note the use of double quotes as there is a space in the string.      

2. Show which customers have received an invoice and sort by name. Remove any duplicates. Your query should return

View the answer

SELECT DISTINCT c.CustABN AS ABN, CustName AS Name
FROM CUSTOMER c, INVOICE i
WHERE c.CustABN = i.CustABN
ORDER BY CustName;

3. Show the customer ABN and name and list all of the items as well as a quantity, description and price for invoice number 21. Your query should return

View the answer

SELECT c.CustABN, CustName, inv.InvoiceNo, Quantity, init.ItemNo, ItemDesc, ItemPrice
FROM CUSTOMER c, INVOICE inv, INVOICEITEM init, ITEM it
WHERE c.CustABN = inv.CustABN
AND init.InvoiceNo = inv.InvoiceNo
AND it.ItemNo = init.ItemNo
AND inv.InvoiceNo = 21;

4. Find the number of invoices for each customer name. Your query should return

View the answer

This is similar to the query from the previous topic where we found the number of invoices for each customer ABN. The answer then was:

SELECT CustABN, COUNT(InvoiceNo)
FROM INVOICE
GROUP BY CustABN;

As we want to display the name of the customers instead of the ABN, we need to join the CUSTOMER and the INVOICE tables. The linking field for the two tables is CustABN.

SELECT c.CustName, COUNT(i.InvoiceNo)
FROM CUSTOMER c, INVOICE i
WHERE c.CustABN = i.CustABN

GROUP BY c.CustName;

We could also use aliases for CustName and COUNT(i.InvoiceNo)

5. Find the customer name, invoice number and value of each invoice. Your query should return

View the answer

SELECT SUM(Quantity * ItemPrice) as InvTotal, CustName, inv.InvoiceNo
FROM InvoiceItem ii, Item i, Invoice inv, Customer c
WHERE ii.ItemNo = i.ItemNo
AND inv.InvoiceNo = ii.InvoiceNo
AND inv.CustABN = c.CustABN
GROUP BY inv.InvoiceNo, CustName;

6. Find the number of invoices for each customer whose name starts with A to E. Try writing this query two ways: once without the HAVING clause, once with the HAVING clause. Your query should return

View the answer

Without the HAVING clause:

SELECT c.CustName, COUNT(i.InvoiceNo)
FROM CUSTOMER c, INVOICE i
WHERE c.CustABN = i.CustABN
AND c.CustName < 'F'
GROUP BY c.CustName;

With the HAVING clause:

SELECT c.CustName, COUNT(i.InvoiceNo)
FROM CUSTOMER c, INVOICE i
WHERE c.CustABN = i.CustABN
GROUP BY c.CustName
HAVING c.CustName < 'F';

7. Find all the customers who have more than one invoice. Could you write this query without the HAVING clause? Your query should return

View the answer

SELECT c.CustName, COUNT(i.InvoiceNo)
FROM CUSTOMER c, INVOICE i
WHERE c.CustABN = i.CustABN
GROUP BY c.CustName
HAVING COUNT(i.InvoiceNo) > 1;

Would this query work?

SELECT c.CustName, COUNT(i.InvoiceNo)
FROM CUSTOMER c, INVOICE i
WHERE c.CustABN = i.CustABN
AND COUNT(i.InvoiceNo) > 1
GROUP BY c.CustName;

View the answer

No. You cannot have a grouping function in the Where clause. So, the condition COUNT(i.InvoiceNo) > 1 will generate a syntax error.

 

Remember
WHERE works on individual rows - only rows that satisfy the condition(s) are included. HAVING works on groups - only groups that satisfy the condition(s) are included. Thus WHERE conditions cannot include grouping functions and HAVING cannot include conditions that operate at the row and not the group level.

 

8. For each customer, find out how much their invoices are worth. Your query should return

View the answer

SELECT c.CustName, SUM(Quantity*ItemPrice)
FROM CUSTOMER c, INVOICE i, INVOICEITEM ii, ITEM it
WHERE c.CustABN = i.CustABN
AND i.InvoiceNo = ii.InvoiceNo
AND ii.ItemNo = it.ItemNo
GROUP BY c.CustName;

9. Find all the customers who have more than one invoice and have the letter t or T in their name. Your query should return

View the answer

SELECT c.CustName, COUNT(i.InvoiceNo)
FROM CUSTOMER c, INVOICE i
WHERE c.CustABN = i.CustABN
AND (c.CustName LIKE '%t%' OR c.CustName LIKE '%T%')
GROUP BY c.CustName;

Note the use of the ( )s. This ensures that the only rows included satisfy:

  • the join condition (c.CustABN = i.CustABN), and
  • have a 't' in their name (c.CustName LIKE '%t%' OR c.CustName LIKE '%T%')

Without the ( )s, namely:

SELECT c.CustName, COUNT(i.InvoiceNo)
FROM CUSTOMER c, INVOICE i
WHERE c.CustABN = i.CustABN
AND c.CustName LIKE '%t%' OR c.CustName LIKE '%T%'
GROUP BY c.CustName;

The WHERE clause is interpreted as rows that satisfy either:

  • the first condition (c.CustABN = i.CustABN AND c.CustName LIKE '%t%'), or
  • the second condition (c.CustName LIKE '%T%').

This gives a rubbish answer.

Remember
Remember AND has higher precedence than OR. So use ( )s in statements that have both AND and OR conditions.

 

10. Find all customers who have invoices dated before August 2005. Your query should return

View the answer

SELECT DISTINCT CustName
FROM CUSTOMER c, INVOICE i
WHERE c.CustABN = i.CustABN
AND TRUNC(InvDate) < DATE '2005-8-1';

11. Find the customer name, invoice no and date (format MON 22 AUGUST 2005) for invoices in August 2005. Your query should return

View the answer

SELECT CustName, InvoiceNo, To_CHAR(InvDate, 'DY DD MONTH YYYY')
FROM CUSTOMER c, INVOICE i
WHERE c.CustABN = i.CustABN
AND TRUNC(InvDate) >= DATE '2005-8-1' AND TRUNC(InvDate) <= DATE '2005-8-31';

Download the questions and answers

Invoice database 3

Now try the following queries on the INVOICE database.

These activities relate to the PowerPoint Presentation “Create Tables” refer to “get your hands dirty”

1. For customers living in Queensland, find the customer name, invoice number and invoice dateYour query should return

CUSTNAME INVOICENO INVDATE
Victor Panels 20 28/AUG/05
Victor Panels 5 13/APR/05
Lenton Holdings 16 25/AUG/05
Australian Drums 17 25/AUG/05
Astian Court Holdings 10 10/JUN/05

 

2. For customers living in Queensland, find the customer name, invoice number and invoice date for invoices with numbers greater than 18 or less than 11 Your query should return

CUSTNAME INVOICENO
Victor Panels 5
Victor Panels 20
Astian Court Holdings 10

3. Find the number of invoices for each customer in Queensland Your query should return

CUSTNAME COUNT(*)
Australian Drums 1
Victor Panels 2
Lenton Holdings 1
Astian Court Holdings 1

4. Can you find the answer to number 3, both using the having clause and not using it? Your query should return

CUSTNAME COUNT(*)
Australian Drums 1
Victor Panels 2
Lenton Holdings 1
Astian Court Holdings 1

Check (invoice database 3)

The Answers to these will be available in Week Tasks multiple table queries.

The specific day is mentioned in announcements.

STUDENT databaseStudent database - more SQL queries

View the Student Tables

1. Which students have Fred Flintstone as their course coordinator?

2 Which students are doing the course Project?

3. For the coordinator with Employee_no AS1234, find his/her name and the average number of units the students he/she advises have completed.

4. For all the coordinators whose employee number start with AS find his/her name and the average number of units the students he/she advises have completed.

STUDENT databaseCheck (Student database)

1. Which students have Fred Flintstone as their course coordinator? View the answer

SELECT Student.Name
FROM Student, Coordinator
WHERE Student.Coord_No=Coordinator.Coord_No
AND Coordinator.Name = 'Fred Flinstone';

Note that for this query all the columns had to be qualified (e.g. Student.Name). The columns by themselves (e.g. Name or Coord_No) would have been ambiguous as they appeared in both tables. If the column name is unique in all tables involved in the query it need not be qualified e.g. the columns Employee_No or Total_Units are unique across both Student and Coordinator.

2 Which students are doing the course Project? View the answer

SELECT Student.Name
FROM Student, Course, Grade
WHERE Student.Student_No=Grade.Student_No
AND Course.Course_No = Grade.Course_No

AND Course.Name = 'Project';

3. For the coordinator with Employee_no AS1234, find his/her name and the average number of units the students he/she advises have completed View the answer

SELECT c.Name, AVG(Total_Units)
FROM Student s, Coordinator c
WHERE s.Coord_No = c. Coord_No
AND Employee_No = 'AS1234'
GROUP BY c.name;

Note that with this example the tables are joined together and the conditions calculated (the effect of the WHERE and AND clauses are computed) before the grouping and aggregations functions are applied.

4. For all the coordinators whose employee number start with AS find his/her name and the average number of units the students he/she advises have completed.View the answer

SELECT c.Name, AVG(Total_Units)
FROM Student s, Coordinator c
WHERE s.Coord_No = c. Coord_No
AND Employee_No LIKE 'AS%'
GROUP BY c.name;

Or another alternate way to write the query would be:

SELECT c.Name, AVG(Total_Units)
FROM Student s, Coordinator c
WHERE s.Coord_No = c. Coord_No
GROUP BY c.name, Employee_No
HAVING Employee_No LIKE 'AS%';

Note to use the Employee_No column in the HAVING clause it needs to appear in the GROUP BY clause.

Download the questions and answers