Appendix A. Oracle’s Old Join Syntax

The join syntax (involving the JOIN, INNER, OUTER, CROSS, LEFT, RIGHT, FULL, ON, and USING keywords) discussed in Chapter 3 was introduced in Oracle9i Database to make Oracle’s join functionality compliant with the ANSI/ISO SQL92 standard known as SQL92. Prior to Oracle9i Database, Oracle supported the join syntax defined in the SQL86 standard. In addition, also prior to Oracle9i Database, Oracle supported outer joins through a proprietary outer join operator. Even though the new SQL92 join syntax is more elegant and powerful, the old join syntax and the proprietary outer join operator are still supported in Oracle Database 10g, for backward compatibility.

If you are writing a new application, we highly recommend that you use the SQL92 join syntax. However, if you have a pre-Oracle9i Database application, you need to understand both syntaxes—the old and the new. In this appendix, we illustrate the old join syntax, and show how it relates to the new syntax. This will help you to migrate an application from the old syntax to the new syntax, and it will help you when you are faced with maintaining an older application.

Old Inner Join Syntax

The following example illustrates the older inner join syntax:

SELECT d.name, l.regional_group
FROM department d, location l
WHERE d.location_id = l.location_id;

The corresponding query with the new syntax is:

SELECT d.name, l.regional_group
FROM department d JOIN location l
ON d.location_id = l.location_id;

Following are the two differences between the old and the new inner join syntax:

  • The old syntax separates tables in the FROM clause using a comma.

  • The old syntax specifies the join condition in the WHERE clause.

Since the old syntax uses the WHERE clause to specify the join condition as well as filter conditions, it may take awhile for you to figure out which component of the WHERE clause is a join condition, and which component is a filter condition.

Old Outer Join Syntax

The old syntax of the outer join is a bit different from that of the inner join, because it includes a special operator called the outer join operator. The outer join operator is a plus sign enclosed in parentheses: (+). This operator is used in a join condition in the WHERE clause following a field name from the table that you wish to be considered the optional table.

For example, to list all the departments even if they are not related to any particular location, you can perform an outer join between the department and the location tables as shown in the following example:

            SELECT d.dept_id, d.name, l.regional_group
            FROM department d, location l
            WHERE d.location_id = l.location_id (+);

   DEPT_ID NAME                 REGIONAL_GROUP
---------- -------------------- ------------------
        10 ACCOUNTING           NEW YORK
        20 RESEARCH             DALLAS
        30 SALES
        40 OPERATIONS           BOSTON

Notice the (+) operator following l.location_id. That makes location the optional table in this join, in the sense that you want to display a row from the department table, even though there exists no corresponding row in the LOCATION table. A corresponding query using the new join syntax is:

SELECT d.dept_id, d.name, l.regional_group
FROM department d LEFT OUTER JOIN location l
ON d.location_id = l.location_id;

In the new outer join syntax, the LEFT (or RIGHT) keyword corresponds to the table from which you want all the rows. This example uses LEFT to point to department, because we want all the rows from the department table irrespective of whether there are coresponding rows in the location table.

Restrictions on Old Outer Join Syntax

There are some rules and restrictions on how you can use the outer join operator in a query. When you use the (+) operator in a query, Oracle doesn’t allow you to perform certain other operations in the same query. We discuss these restrictions and some of the workarounds in the following list:

  • The outer join operator can appear on only one side of an expression in the join condition. You get an ORA-01468 error if you attempt to use it on both sides. For example:

                         SELECT d.dept_id, d.name, l.regional_group
                         FROM department d, location l
                         WHERE d.location_id (+) = l.location_id(+);
    WHERE d.location_id (+) = l.location_id(+)
                            *
    ERROR at line 3:
    ORA-01468: a predicate may reference only one outer-joined table

    What this means is that the outer join operation using the (+) operator is unidirectional. You can’t perform a bidirectional outer join (known as a full outer join) using the (+) operator.

Tip

If you are attempting a full outer join by placing the (+) operator on both sides in the join condition, please refer to Section A.2.2, which follows this section.

  • If a join involves more than two tables, then one table can’t be outer joined with more than one other table in the query. Consider the following tables:

                         DESC employee
    Name                                      Null?    Type
    ----------------------------------------- -------- --------------
    EMP_ID                                    NOT NULL NUMBER(5)
    FNAME                                              VARCHAR2(20)
    LNAME                                              VARCHAR2(20)
    DEPT_ID                                   NOT NULL NUMBER(5)
    MANAGER_EMP_ID                                     NUMBER(5)
    SALARY                                             NUMBER(5)
    HIRE_DATE                                          DATE
    JOB_ID                                             NUMBER(3)
    
    DESC job
     Name                            Null?    Type
     ------------------------------- -------- ----
     JOB_ID                          NOT NULL NUMBER(3)
     FUNCTION                                 VARCHAR2(30)
    
    DESC department
     Name                            Null?    Type
     ------------------------------- -------- ----
     DEPT_ID                         NOT NULL NUMBER(5)
     NAME                                     VARCHAR2(20)
     LOCATION_ID                              NUMBER(3)

    If you want to list the job function and department name of all the employees, and you want to include all the departments and jobs that don’t have any corresponding employees, you would probably attempt to join the employee table with the job and department tables, and make both the joins outer joins. However, since one table can’t be outer-joined with more than one table you get the following error:

                         SELECT e.lname, j.function, d.name
                         FROM employee e, job j, department d
                         WHERE e.job_id (+) = j.job_id
                         AND e.dept_id (+) = d.dept_id;
    
    WHERE e.job_id (+) = j.job_id
                       *
    ERROR at line 3:
    ORA-01417: a table may be outer joined to at most one other table

    As a workaround, you can create a view with an outer join between two tables, and then outer join the view to the third table:

    CREATE VIEW v_emp_job
    AS SELECT e.dept_id, e.lname, j.function
    FROM employee e, job j
    WHERE e.job_id (+) = j.job_id;
    
    SELECT v.lname, v.function, d.name
    FROM v_emp_job v, department d
    WHERE v.dept_id (+) = d.dept_id;

    Instead of creating a view, you can use an inline view to achieve the same result:

    SELECT v.lname, v.function, d.name
    FROM (SELECT e.dept_id, e.lname, j.function
          FROM employee e, job j
          WHERE e.job_id (+) = j.job_id) v, department d
    WHERE v.dept_id (+) = d.dept_id;

    Inline views are discussed in Chapter 5.

  • A condition containing the (+) operator may not use the IN operator. For example:

                         SELECT e.lname, j.function
                         FROM employee e, job j
                         WHERE e.job_id (+) IN (668, 670, 667);
    WHERE e.job_id (+) IN (668, 670, 667)
                       *
    ERROR at line 3:
    ORA-01719: outer join operator (+) not allowed in operand of OR or IN
  • An outer join condition containing the (+) operator may not be combined with another condition using the OR operator. For example:

                         SELECT e.lname, d.name
                         FROM employee e, department d
                         WHERE e.dept_id = d.dept_id (+)
                         OR d.dept_id = 10;
    WHERE e.dept_id = d.dept_id (+)
                    *
    ERROR at line 3:
    ORA-01719: outer join operator (+) not allowed in operand of OR or IN
  • A condition containing the (+) operator may not involve a subquery. For example:

                         SELECT e.lname
                         FROM employee e
                         WHERE e.dept_id (+) =
                         (SELECT dept_id FROM department WHERE name = 'ACCOUNTING'),
    (SELECT DEPT_ID FROM DEPARTMENT WHERE NAME = 'ACCOUNTING')
                                                             *
    ERROR at line 4:
    ORA-01799: a column may not be outer-joined to a subquery

    As a workaround, you can use an inline view to achieve the desired effect:

    SELECT e.lname
    FROM employee e,
    (SELECT dept_id FROM department WHERE name = 'ACCOUNTING') V
    WHERE e.dept_id (+) = v.dept_id;

Full Outer Join Using the Old Syntax

In the previous section, you saw that a full outer join using the (+) operator is not allowed. A UNION of two SELECT statements is a workaround for this problem. In the following example, the first SELECT represents an outer join in which department is the optional table. The second SELECT has the location table as the optional table. Between the two SELECTS, you get all locations and all departments. The UNION operation eliminates duplicate rows, and the result is a full outer join:

               SELECT d.dept_id, d.name, l.regional_group
               FROM department d, location l
               WHERE d.location_id (+) = l.location_id
               UNION
               SELECT d.dept_id, d.name, l.regional_group
               FROM department d, location l
               WHERE d.location_id = l.location_id (+) ;

   DEPT_ID NAME                 REGIONAL_GROUP
---------- -------------------- ----------------
        10 ACCOUNTING           NEW YORK
        20 RESEARCH             DALLAS
        30 SALES
        40 OPERATIONS           BOSTON
                                CHICAGO
                                SAN FRANCISCO

6 rows selected.

As you can see, this UNION query includes all the rows you would expect to see in a full outer join. UNION queries are discussed in Chapter 7.

Tip

Using the ANSI/ISO-compatible join syntax introduced in Oracle9i Database you can perform a full outer join in a much more straightforward way than shown in the previous example. See Section 3.3.3 in Chapter 3.

Advantages of the New Join Syntax

The ANSI join syntax represents a bit of an adjustment to developers who are used to using Oracle’s traditional join syntax, including the outer join operator (+). However, there are several advantages to using the syntax introduced in Oracle9i Database:

  • The new join syntax follows the ANSI standard, making your code more portable.

  • The ON and USING clauses keep join conditions away from the filter conditions in the WHERE clause. This enhances development productivity and the maintainability of your code.

  • The ANSI/ISO syntax makes it possible to perform a full outer join without having to perform a UNION of two SELECT queries.

We recommend that while working with Oracle9i Database and later Oracle releases, you use the new join syntax instead of the traditional join syntax.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.12.108.175