SQL Joins
SQL Joins
After completing this lesson, you should be able to do the following: 1. Write SELECT statements to access data from more than one table using equality and non equality joins. 2. View data that generally does not meet a join condition by using outer joins 3. Join a table to itself Schema - 1 (EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno) DEPT (deptno, dname, loc))
A CROSS JOIN implements a Cartesian product, which returns rows combined from both tables.
It matches every row in one table against every row in another table. For example, if you have 3 rows in one table and 2 rows in another youll have 2 times 3, or 6, rows in the result set. ANSI Standard (Oracle 9i Onwards) Cross Join
Select e.empno, e.ename, e.sal, e.deptno, d.dname From emp e CROSS JOIN dept d
An INNER JOIN implements an equijoin, which returns rows combined from both tables when the values in the join condition match. Join conditions can include one or more columns. A NATURAL JOIN implements an equijoin, which returns rows combined from both tables when the values in the join condition match. While the join conditions can include one or more columns, you have no choice in selecting the join columns. A NATURAL JOIN checks the definition of both tables (in the data catalog or metadata) and looks for like named columns. It then joins the table based on the values of all like named columns from both tables. One might say its an unnatural behavior because a developer has no way to override it.
ANSI Standard (Oracle 9i Onwards) Natural Join
Select empno, ename, sal, deptno, dname From emp NATURAL JOIN dept
Schema - 2 (EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno) DEPT (deptno, dname, loc) LOC (loc, loc_desc, loc_cat))
ANSI Standard (Oracle 9i Onwards) Natural Join For three tables.
Select empno, sal, deptno, dname, loc, loc_desc, loc_cat From emp NATURAL JOIN dept NATURAL JOIN loc
Schema - 3 (Table1 (col1, col2, col3, col4) -- Parent Table Table2 (E1, E2, E3, E4, col1, col2,) -- Child Table)
ANSI Standard (Oracle 9i Onwards) Natural Join For composite primary key.
We cant write the natural join for Table1 and Table2 As Table1 has composite primary key.
A LEFT JOIN implements an equijoin and relative complement, which returns rows combined from both tables when the values in the join condition match and the rows in the left table that arent found in the right table. This makes a LEFT JOIN a combination of an INNER JOIN and a relative complement of the table on the right of the join. This nuance becomes important when we examine the (+) semantic implemented by Oracle.
ANSI Standard (Oracle 9i Onwards) Left Outer Join - Natural
Select empno, ename, sal, deptno, dname From emp NATURAL LEFT OUTER JOIN dept
A RIGHT JOIN implements an equijoin and relative complement, which returns rows combined from both tables when the values in the join condition match and the rows in the right table that arent found in the left table. This makes a RIGHT JOIN the opposite of a LEFT JOIN. Naturally, it is also a combination of an INNER JOIN and a relative complement of the left table. Like the LEFT JOIN, this nuance becomes important when we examine the (+) semantic implemented by Oracle.
ANSI Standard (Oracle 9i Onwards) Right Outer Join - Natural
Select empno, ename, sal, deptno, dname From emp NATURAL RIGHT OUTER JOIN dept
A FULL JOIN implements an equijoin and both relative complements, which returns rows combined from both tables when the values in the join condition match and the rows in both the left and right tables that arent found in their respective other tables. This makes a FULL JOIN a
combination of an INNER JOIN and relative complements of the both tables. This type of join cant be done with the (+) alone in the older syntax. It requires left and right outer queries glued together by a UNION set operator. The UNION set operator eliminates duplicate from the intersection of the two tables, which are created by gluing together two outer joins.
ANSI Standard (Oracle 9i Onwards) Full Outer Join - Natural
Select empno, ename, sal, deptno, dname From emp NATURAL FULL OUTER JOIN dept
Non-equijoins:
Rule(s): 1. A non-equijoin doesnt have an equijoin statement. 2. A non-equijoin that uses the CROSS JOIN doesnt have a join in the FROM clause. 3. A non-equijoin that uses a comma separated list of tables doesnt have an equijoin in the WHERE clause.
EMPNO ENAME SAL ------ ------- -----7839 KING 5000 7698 BLAKE 2850 7782 CLARK 2450 7566 JONES 2975 7654 MARTIN 1250 7499 ALLEN 1600 7844 TURNER 1500 7900 JAMES 950 ... 14 rows selected.
GRADE LOSAL HISAL ----- ----- -----1 700 1200 2 1201 1400 3 1401 2000 4 2001 3000 5 3001 9999
Salary in the EMP table is between lo sal and hi sal in the SALGRADE table
Self Join:
Rule(s):
1. A self join is required to get the hierarchal relationship in the same table. 2. Use different aliases to the same table to perform a self join.
ANSI Standard (Oracle 9i Onwards) Self Join
Select e.ename || ' Works for ' ||m.ename from emp e INNER JOIN emp m ON e.mgr=m.empno
DROP TABLE EMP; DROP TABLE DEPT; CREATE TABLE DEPT (DEPTNO NUMBER(2) CONSTRAINT pk_dept PRIMARY KEY, DNAME VARCHAR2(14), LOC VARCHAR2(13) ); INSERT INTO DEPT VALUES (10, 'ACCOUNTING', 'NEW YORK'); INSERT INTO DEPT VALUES (20, 'RESEARCH', 'DALLAS'); INSERT INTO DEPT VALUES (30, 'SALES', 'CHICAGO');
(EMPNO NUMBER(4) CONSTRAINT pk_emp PRIMARY KEY, ENAME VARCHAR2(10), JOB VARCHAR2(9), MGR NUMBER(4), HIREDATE DATE, SAL NUMBER(7, 2), COMM NUMBER(7, 2), DEPTNO NUMBER(2) CONSTRAINT fk_emp_dept REFERENCES dept(deptno)); INSERT INTO EMP VALUES (7369, 'SMITH', 'CLERK', 7902, TO_DATE('17-DEC-1980', 'DD-MON-YYYY'), 800, NULL, 20);
INSERT INTO EMP VALUES (7499, 'ALLEN', 'SALESMAN', 7698, TO_DATE('20-FEB-1981', 'DD-MON-YYYY'), 1600, 300, 30); INSERT INTO EMP VALUES (7521, 'WARD', 'SALESMAN', 7698, TO_DATE('22-FEB-1981', 'DD-MON-YYYY'), 1250, 500, 30); INSERT INTO EMP VALUES (7566, 'JONES', 'MANAGER', 7839, TO_DATE('2-APR-1981', 'DD-MON-YYYY'), 2975, NULL, 20); INSERT INTO EMP VALUES (7654, 'MARTIN', 'SALESMAN', 7698, TO_DATE('28-SEP-1981', 'DD-MON-YYYY'), 1250, 1400, 30); INSERT INTO EMP VALUES (7698, 'BLAKE', 'MANAGER', 7839, TO_DATE('1-MAY-1981', 'DD-MON-YYYY'), 2850, NULL, 30); INSERT INTO EMP VALUES (7782, 'CLARK', 'MANAGER', 7839, TO_DATE('9-JUN-1981', 'DD-MON-YYYY'), 2450, NULL, 10); INSERT INTO EMP VALUES (7788, 'SCOTT', 'ANALYST', 7566, TO_DATE('09-DEC-1982', 'DD-MON-YYYY'), 3000, NULL, 20); INSERT INTO EMP VALUES (7839, 'KING', 'PRESIDENT', NULL, TO_DATE('17-NOV-1981', 'DD-MON-YYYY'), 5000, NULL, 10); INSERT INTO EMP VALUES (7844, 'TURNER', 'SALESMAN', 7698, TO_DATE('8-SEP-1981', 'DD-MON-YYYY'), 1500, INSERT INTO EMP VALUES (7876, 'ADAMS', 'CLERK', INSERT INTO EMP VALUES (7900, 'JAMES', 'CLERK', 0, 30);
7788, TO_DATE('12-JAN-1983', 'DD-MON-YYYY'), 1100, NULL, 20); 7698, TO_DATE('3-DEC-1981', 'DD-MON-YYYY'), 950, NULL, 30);
INSERT INTO EMP VALUES (7902, 'FORD', 'ANALYST', 7566, TO_DATE('3-DEC-1981', 'DD-MON-YYYY'), 3000, NULL, 20); INSERT INTO EMP VALUES (7934, 'MILLER', 'CLERK', 7782, TO_DATE('23-JAN-1982', 'DD-MON-YYYY'), 1300, NULL, NULL);
INSERT INTO EMP VALUES (7856, 'DEEP', 'ANALYST', 7566, TO_DATE('3-DEC-1981', 'DD-MON-YYYY'), 9000, NULL, NULL); INSERT INTO EMP VALUES (7857, 'KITE', 'CLERK', COMMIT; 7782, TO_DATE('23-JAN-1982', 'DD-MON-YYYY'), 5100, NULL, NULL);
Drop table loc; Create table loc (loc varchar2(10), loc_desc varchar2(10), loc_cat varchar2(10)); Alter table loc add constraint pk_loc primary key (loc);
INSERT INTO LOC VALUES ('NEW YORK', USA, C); INSERT INTO LOC VALUES ('DALLAS', USA, C); INSERT INTO LOC VALUES ('CHICAGO', USA, C); INSERT INTO LOC VALUES ('BOSTON', USA, C); INSERT INTO LOC VALUES ('DELHI', INDIA, HC);
Drop table table1; Create table table1 (col1 number, col2 number, col3 number, col4 number); Alter table table1 add constraint pk_table1 primary key (col1, col2); Insert into table1 values (10, 11, 50, 100); Insert into table1 values (11, 11, 50, 100); Insert into table1 values (12, 11, 50, 100); Insert into table1 values (13, 11, 50, 100); Insert into table1 values (13, 12, 50, 100);
Create table table2 (e1 number, e2 number, e3 number, e4 number, col1 number, col2 number); Alter table table2 add constraint pk_table2 primary key (e1); Alter table table2 add constraint fk_pk_table1 foreign key(col1, col2) references table1(col1, col2); Insert into table2 values (1, 2, 3, 4, 10, 11); Insert into table2 values (2, 12,13, 14, 10, 11); Insert into table2 values (3, 22, 23, 24, 13, 11); Insert into table2 values (4, 32, 33, 34, 13, 12); Insert into table2 values (5, 42, 43, 44, 10, 11); Insert into table2 values (6, 52, 53, 54, 12, 11); Insert into table2 values (7, 62, 36, 64, 11, 11); Insert into table2 values (8, 72, 73, 74, 11, 11); Insert into table2 values (9, 62, 36, 64, null, null); Insert into table2 values (10, 72, 73, 74, null, null); COMMIT;