Joins
A join results from a statement that combines columns from two or more tables into a single view. From this view, you can retrieve, insert, update, or delete data, provided it is not read-only.
*Note: This section primarily discusses joining tables using SELECT statements. However, you can also create joins with INSERT, UPDATE, and DELETE statements by applying a single statement to more than one table. SQL Engine Reference describes these SQL statements and how to optimize joined views.
You can retrieve data from tables by listing each table or view name in a FROM clause. Use a WHERE clause to specify one or more join conditions. A join condition compares an expression that references a column value from one table to an expression that references a column value from another table.
When data is properly normalized, most joins associate values based on some specified key value. This allows you to extract data in terms of referential integrity relationships. For example, if you want to know which professor teaches each class, you can create a join based on the Faculty ID, which is a foreign key in the Class table and a primary key in the Person table:
SELECT DISTINCT Class.Name, Person.Last_Name
FROM Class, Person, Faculty
WHERE Class.Faculty_ID = Person.ID
AND Class.Faculty_ID = Faculty.ID;
This example joins two tables on the basis of common values in a common column: Faculty ID.
You can also join tables by making numeric comparisons between columns of like data types. For example, you can compare columns using <, >, or =. The following self-join on the Faculty table identifies all faculty members whose salary was higher than each faculty member (this would produce considerably more records than the faculty table contains):
SELECT A.ID, A.Salary, B.ID, B.Salary
FROM Faculty A, Faculty B
WHERE B.Salary > A.Salary;
Similar comparisons of dates, times, and so forth can produce many useful and meaningful results.
When joining columns, choose columns that are of the same data type when possible. For example, comparing two NUMERIC columns is more efficient than comparing a NUMERIC column with an INTEGER column. If the columns are not of the same data type but are both numeric or strings, Pervasive PSQL scans both the tables and applies the join condition as a restriction to the results.
When you use string type columns in a WHERE clause, one column in the join condition can be a computed string column. This allows you to concatenate two or more strings and use a join condition to compare them to a single string from another table.
The way in which Pervasive PSQL handles a join depends on whether the join condition contains an index column.
If the join condition contains a column that is defined as an index, performance improves. Using the index to sort rows in the corresponding table, Pervasive PSQL selects only rows that meet the restriction clause condition.
If the join condition does not contain a column that is defined as an index, performance is less efficient. Pervasive PSQL reads each row in each table to select rows that meet the restriction clause condition. To enhance performance, you can create an index in one of the tables before executing the join. This is especially helpful if the query is one that you perform often.
Joining Tables with Other Tables
To specify a join using a SELECT statement, use a FROM clause to list the relevant tables and a WHERE clause to specify the join condition and the restriction. The following example also uses aliases to simplify the statement.
SELECT Student_ID, Class_ID, Name
FROM Enrolls e, Class cl
WHERE e.Class_ID = cl.ID;
The next example joins three tables:
SELECT p.ID, Last_Name, Name
FROM Person p, Enrolls e, Class cl
WHERE p.ID = e.Student_ID AND e.Class_ID = cl.ID;
The next example retrieves a list of students who received a grade lower than a 3.0 in English.
SELECT First_Name, p.Last_Name
FROM Person p, Student s, Enrolls e, Class cl
WHERE s.ID = e.Student_ID
AND e.Class_ID = cl.ID
AND s.ID = p.ID
AND cl.Name = 'ACC 101'
AND e.Grade < 3.0;
In this example, the first three conditions in the WHERE clause specify the join between the four tables. The next two conditions are restriction clauses connected by the Boolean operator AND.
Joining Views with Tables
To join a view with one or more tables, include a view name in the FROM clause. The view you specify can include columns from a single table or from several joined tables.
Types of Joins
Pervasive PSQL supports equal joins, nonequal joins, null joins, Cartesian product joins, self joins, and left, right, and full outer joins.
For more information on the syntax of joins, see the following topics:
In SQL Engine Reference: SELECT
In SQL Engine Reference: JOIN
Equal Joins
An equal join occurs when you define the two join columns as equal. The following statement defines an equal join.
SELECT First_Name, Last_Name, Degree, Residency
FROM Person p, Student s, Tuition t
WHERE p.ID = s.ID AND s.Tuition_ID = t.ID;
Nonequal Joins
You can join tables based on a comparison operation. You can use the following operators in nonequal joins:
The following WHERE clause illustrates a join that uses a greater than or equal operator.
SELECT Name, Section, Max_Size, Capacity, r.Building_Name, Number
FROM Class cl, Room r
WHERE Capacity >= Max_Size;
Cartesian Product Joins
A Cartesian product join associates each row in one table with each row in another table. Pervasive PSQL reads every row in one table once for each row in the other table.
On large tables, a Cartesian product join can take a significant amount of time to complete since Pervasive PSQL must read the following number of rows to complete this type of join:
(# of rows in one table) * (# of rows in another table)
For example, if one table contains 600 rows and the other contains 30, Pervasive PSQL reads 18,000 rows to create the Cartesian product join of the tables.
The following statement produces a Cartesian product join on the Person and Course tables in the sample database:
SELECT s.ID, Major, t.ID, Degree, Residency, Cost_Per_Credit
FROM Student s, Tuition t#
Self Joins
In a self join, you can specify a table name in the FROM clause more than once. When you specify a self join, you must assign aliases to each instance of the table name so that Pervasive PSQL can distinguish between each occurrence of the table in the join.
The following example lists all the people who have a permanent address in the same state as the person named Jason Knibb. The query returns the ID, first name, last name, current phone number, and e-mail address.
SELECT p2.ID, p2.First_Name, p2.Last_Name, p2.Phone, p2.EMail_Address
FROM Person p1, Person p2
WHERE p1.First_Name = 'Jason' AND p1.Last_Name = 'Knibb' and p1.Perm_State = p2.Perm_State
Left, Right, Full Outer Joins
Information about outer joins can be found in SQL Engine Reference. In SQL Engine Reference, see SELECT and JOIN.