You are on page 1of 1

Chapter 3: Selecting 93

JOIN in the preceding example; note that this particular FROM clause performs
exactly the same function with or without the parentheses:
FROM ( ( ( customer
INNER JOIN sales_order
ON sales_order.cust_id = customer.id )
INNER JOIN sales_order_items
ON sales_order_items.id = sales_order.id )
INNER JOIN product
ON product.id = sales_order_items.prod_id )
Parentheses are useful in arithmetic expressions when you have to override the
natural order of execution of the different operators (e.g., if you want addition to
come before multiplication). Even if theyre not required, parentheses in arith-
metic expressions help the reader understand the order of evaluation. Those
arguments do not apply as strongly to parentheses in the FROM clause. First of
all, there is no difference in precedence among the different join operators like
INNER JOIN and LEFT OUTER JOIN; without parentheses theyre simply
evaluated from left to right. Also, FROM clauses tend to be long, drawn-out
affairs where matching parentheses appear far apart, so theyre not much help to
the reader. Even in the simple example above, its hard to see what the parenthe-
ses are doing; an argument can be made that the version without parentheses is
easier to read.
Having said that, parentheses in the FROM clause are sometimes necessary
and helpful. The following example illustrates that point using the four tables in
the ASADEMO database discussed above: customer, product, sales_order, and
sales_order_items. The requirement is to show how many of each kind of shirt
were sold to each customer in Washington, D.C., including combinations of
product and customer that had no sales. In other words, show all the combina-
tions of Washington customers and shirt products, whether or not any actual
sales were made.
At first glance it appears four joins are required: a CROSS JOIN between
customer and product to generate all possible combinations, a LEFT OUTER
JOIN between customer and sales_order to include customers whether or not
they bought anything, a LEFT OUTER JOIN between product and
sales_order_items to include products whether or not any were sold, and an
INNER JOIN between sales_order and sales_order_items to match up the orders
with their order items.
Perhaps it is possible to write these four joins, in the right order, with or
without parentheses, but a simpler solution uses a divide-and-conquer approach:
n First, separately and independently compute two different virtual tables: the
CROSS JOIN between customer and product, and the INNER JOIN
between sales_order and sales_order_items.
n Second, perform a LEFT OUTER JOIN between the first and second vir-
tual tables. Parentheses are used to separate the first step from the second.
Here is the pseudocode for the FROM clause using this approach:
SELECT ...
FROM ( all the combinations of customer and product )
LEFT OUTER JOIN
( all the matching combinations of sales_order and sales_order_items )
WHERE ...

You might also like