The reason for the lack of data is that there are no rows in the Orders table associated with that customer.. Similarly, you can see no refund data for either the 9/2/2009 order from Nat
Trang 1The line between the Customers and Orders tables is on the CustomerID
columns because the CustomerID is the common link between these two tables
Similarly, the line between the Orders and Refunds tables is on the OrderID
columns because the OrderID is the common link between these two tables
In other words, the Orders table is related to the Customers table by customer
There must be a customer for an order to exist The Refunds table is related to
the Orders table by the order There must be an order before a refund is issued
Note that the Refunds table is not directly related to the Customers table
How-ever, by joining all three tables together, we will be able to determine which
customer a given refund was for
Let’s now examine the contents of each table The Customers table has these
values:
CustomerID FirstName LastName
The Orders table has this data:
OrderID CustomerID OrderDate OrderAmount
The Refunds table contains this data:
RefundID OrderID RefundDate RefundAmount
Trang 2Notice that three out of the four customers have placed orders Likewise, only two refunds have been issued for the four orders placed
Left Joins
Let’s now create aSELECTstatement that joins all three tables together, using a
LEFT JOIN:
SELECT
Customers.FirstName AS 'First Name',
Customers.LastName AS 'Last Name',
Orders.OrderDate AS 'Order Date',
Orders.OrderAmount AS 'Order Amt',
Refunds.RefundDate AS 'Refund Date',
Refunds.RefundAmount AS 'Refund Amt'
FROM Customers
LEFT JOIN Orders
ON Customers.CustomerID ¼ Orders.CustomerID
LEFT JOIN Refunds
ON Orders.OrderID ¼ Refunds.OrderID
ORDER BY Customers.CustomerID, Orders.OrderID, RefundID
The resulting data looks like:
First Name Last Name Order Date Order Amt Refund Date Refund Amt
D A T A B A S E D I F F E R E N C E S : O r a c l e
Unlike SQL Server and MySQL, Oracle typically displays dates in a DD-MMM-YY format For example, the date 2009-09-02 in the previous table will display as 02-SEP-09 in Oracle However,
no matter which database you’re using, the exact format in which dates are displayed will vary, depending on how your database was set up.
Chapter 12 ■ Combining Tables with an Outer Join
122
Trang 3Before analyzing the previous SELECT statement, notice that there are two
interesting aspects of the data you can see First, Adam Petrie has no data shown
other than his name The reason for the lack of data is that there are no rows in
the Orders table associated with that customer The power of the outer join
comes from the fact that you can see some data for Adam Petrie, even if he has no
orders If we had specified anINNER JOINrather than aLEFT JOIN, you would
see no rows at all for Adam
Similarly, you can see no refund data for either the 9/2/2009 order from Natalie
Lopez or the order from Brenda Harper—because there are no rows in the
Re-funds table associated with those orders If we had specified an INNER JOIN
rather than aLEFT JOIN, you would see no rows for those two orders
Let’s now look at theSELECTstatement itself The first few lines that specify the
columns are nothing that you haven’t seen before Notice that rather than using
table aliases, we’re listing all the columns with their full names, with the table as a
prefix
The first table listed is the Customers table This table is shown after theFROM
keyword The second table shown is the Orders table, which appears after the
first LEFT JOIN keyword The subsequentON clause specifies how the Orders
table is linked to the Customers table The third table shown is the Refunds table,
which appears after the secondLEFT JOINkeyword The subsequentONclause
specifies how the Refunds table is joined to the Orders table
It is critical to realize that the order in which tables are listed in reference to the
LEFT JOINkeyword is significant When specifying aLEFT JOIN, the table to
the left of LEFT JOIN is always the primary table The table to the right of
the LEFT JOINis the secondary table When joining between the primary and
secondary tables, we want all rows in the primary table, even if there are no
matches with any rows in the secondary table
In the first specified LEFT JOIN, the Customers table is on the left and the
Orders table is on the right of theLEFT JOIN, which signifies that Customers is
primary and Orders is secondary In other words, we want to see all selected data
from the Customers table, even if there isn’t a corresponding match in the
secondary table for that row
Similarly, in the second LEFT JOIN, the Orders table is to the left and the
Refunds table is to the right That means that we are specifying Orders as primary
Trang 4and Refunds as secondary in this join We want all orders, even if there are no matching refunds for that order
Finally, we included anORDER BYclause Notice that the fields specified in the
ORDER BYare not selected in the original columnlist.
Testing for NULL Values
In the previous SELECT, we had one customer with no orders and two orders with no associated refunds Unlike the INNER JOIN, the LEFT JOIN allows these rows with missing values to appear
To test your understanding of theLEFT JOIN, let’s now ask how we would list
only those orders for which no refund was issued The solution involves adding a
WHEREclause that tests for NULL values, as follows:
SELECT
Customers.FirstName AS 'First Name',
Customers.LastName AS 'Last Name',
Orders.OrderDate AS 'Order Date',
Orders.OrderAmount AS 'Order Amt'
FROM Customers
LEFT JOIN Orders
ON Customers.CustomerID ¼ Orders.CustomerID
LEFT JOIN Refunds
ON Orders.OrderID ¼ Refunds.OrderID
WHERE Orders.OrderID IS NOT NULL
AND Refunds.RefundID IS NULL
ORDER BY Customers.CustomerID, Orders.OrderID
The resulting data is:
First Name Last Name Order Date Order Amt
TheWHERE clause first tests Orders.OrderID to make sure that it isn’t NULL Doing so ensures that you don’t see customers who never placed an order The second portion of theWHEREclause tests Refunds.RefundID to make sure that it
is NULL This ensures that you only see orders that don’t match a refund Chapter 12 ■ Combining Tables with an Outer Join
124
Trang 5Right Joins
The previous SELECT statements utilized the LEFT JOIN keyword The good
news about right joins is that they are identical in concept to the left join The
only difference between left and right joins is the order in which the two tables in
the join are listed
In left joins, the primary table is listed to the left of theLEFT JOINkeyword The
secondary table, which may or may not contain matching rows, is listed to
the right of theLEFT JOINkeyword
In right joins, the primary table is listed to the right of theRIGHT JOINkeyword
The secondary table is listed to the left of theRIGHT JOINkeyword That’s the
only difference
TheFROMclause of the previousSELECTstatement was:
FROM Customers
LEFT JOIN Orders
ON Customers.CustomerID ¼ Orders.CustomerID
LEFT JOIN Refunds
ON Orders.OrderID ¼ Refunds.OrderID
If we desire to restate this using right joins, we could change it to:
FROM Refunds
RIGHT JOIN Orders
ON Orders.OrderID ¼ Refunds.OrderID
RIGHT JOIN Customers
ON Customers.CustomerID ¼ Orders.CustomerID
The point to note is that it’s only the order in which tables are listed before and
after theRIGHT JOINthat matters The order in which columns are listed after
theONkeyword has no significance
Basically, this means that it’s completely unnecessary to ever use theRIGHT JOIN
keyword Anything that can be specified with aRIGHT JOINcan be specified with
aLEFT JOIN Our suggestion is to stick with theLEFT JOIN, since we intuitively
tend to think in terms of listing more important, or primary, tables first
Table Order in Outer Joins
We previously noted that the order in which tables were specified in an inner join
was not material The same is not true of outer joins, since the order that tables