Based on the SQLD exam syllabusReport an error
ON of the FROM clause, leaving only row-filtering conditions in WHERE.LEFT, RIGHT, and FULL OUTER JOIN keep every row of the table on the side named by the direction. FULL cannot be written with Oracle's (+).Moving yesterday's EQUI join to ANSI notation, you use JOIN instead of a comma and ON instead of WHERE.
SELECT E.ENAME, D.DNAME
FROM EMP E INNER JOIN DEPT D ON E.DEPTNO = D.DEPTNO
WHERE E.DEPTNO = 10
ORDER BY E.ENAME;ENAME DNAME
---------- --------------
CLARK ACCOUNTING
KING ACCOUNTING
MILLER ACCOUNTINGINNER can be omitted. Writing just JOIN means INNER JOIN.=. A Non-EQUI join can be expressed in ANSI too.If you write only JOIN and give no join condition, it is a syntax error. If you need a Cartesian product, use CROSS JOIN.
SELECT COUNT(*) FROM EMP JOIN DEPT;SELECT COUNT(*) FROM EMP JOIN DEPT
*
ERROR at line 1:
ORA-02000: missing ON or USING keywordNATURAL JOIN finds all the columns with the same name in the two tables and connects rows whose values in those columns are equal. You do not write a condition separately.
SELECT ENAME, DEPTNO, DNAME FROM EMP NATURAL JOIN DEPT WHERE DEPTNO = 10 ORDER BY ENAME;ENAME DEPTNO DNAME
---------- ---------- --------------
CLARK 10 ACCOUNTING
KING 10 ACCOUNTING
MILLER 10 ACCOUNTINGE.DEPTNO = D.DEPTNO.DEPTNO without a prefix does not raise ORA-00918.Looking at it with SELECT * reveals the merged form.
SELECT * FROM DEPT NATURAL JOIN EMP WHERE EMPNO = 7839; DEPTNO DNAME LOC EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- -------------- ------------- ---------- ---------- --------- ---------- ---------- ---------- ----------
10 ACCOUNTING NEW YORK 7839 KING PRESIDENT 1981-11-17 5000SELECT * FROM DEPT D JOIN EMP E ON D.DEPTNO = E.DEPTNO WHERE EMPNO = 7839; DEPTNO DNAME LOC EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- -------------- ------------- ---------- ---------- --------- ---------- ---------- ---------- ---------- ----------
10 ACCOUNTING NEW YORK 7839 KING PRESIDENT 1981-11-17 5000 10The merged DEPTNO is not a column of either one table. Attaching a table alias is an error.
SELECT E.ENAME, E.DEPTNO FROM EMP E NATURAL JOIN DEPT D;SELECT E.ENAME, E.DEPTNO FROM EMP E NATURAL JOIN DEPT D
*
ERROR at line 1:
ORA-25155: column used in NATURAL join cannot have qualifierE.ENAME is not a common column, so a prefix is fine. What caused the problem is E.DEPTNO.If there is no common column at all, NATURAL JOIN becomes a join with no condition, that is, a Cartesian product.
SELECT COUNT(*) FROM EMP NATURAL JOIN SALGRADE; COUNT(*)
----------
70NAME that both tables have), that column also goes into the condition. The result of a NATURAL JOIN depends on column names.USING lets you choose directly which of the same-named columns to use for the join. You write the column name in parentheses.
SELECT ENAME, DEPTNO, DNAME FROM EMP JOIN DEPT USING (DEPTNO) WHERE DEPTNO = 10 ORDER BY ENAME;ENAME DEPTNO DNAME
---------- ---------- --------------
CLARK 10 ACCOUNTING
KING 10 ACCOUNTING
MILLER 10 ACCOUNTINGA column used in USING is also merged into one, like in NATURAL JOIN, so you cannot attach a prefix. It is the same in SELECT and in WHERE.
SELECT ENAME, DEPTNO FROM EMP E JOIN DEPT D USING (DEPTNO) WHERE E.DEPTNO = 10;SELECT ENAME, DEPTNO FROM EMP E JOIN DEPT D USING (DEPTNO) WHERE E.DEPTNO = 10
*
ERROR at line 1:
ORA-25154: column part of USING clause cannot have qualifier| Notation | Join columns | Prefix on common column | Common column display |
|---|---|---|---|
NATURAL JOIN | All same-named columns (automatic) | Not allowed (ORA-25155) | Once |
JOIN ... USING (column) | The columns specified in parentheses | Not allowed (ORA-25154) | Once |
JOIN ... ON condition | As written in the condition | Required (otherwise ORA-00918) | Both sides separately |
CROSS JOIN is used when you create a Cartesian product on purpose.
SELECT COUNT(*) FROM EMP CROSS JOIN DEPT; COUNT(*)
----------
56It is a join that takes no condition, so attaching ON is a syntax error.
SELECT COUNT(*) FROM EMP CROSS JOIN DEPT ON EMP.DEPTNO = DEPT.DEPTNO;SELECT COUNT(*) FROM EMP CROSS JOIN DEPT ON EMP.DEPTNO = DEPT.DEPTNO
*
ERROR at line 1:
ORA-03048: SQL reserved word 'ON' is not syntactically valid following '...(*) FROM EMP CROSS JOIN DEPT 'The direction points to the left table or the right table relative to the JOIN keyword. All rows on that side are kept even without a match.
SELECT D.DEPTNO, D.DNAME, E.ENAME
FROM DEPT D LEFT OUTER JOIN EMP E ON D.DEPTNO = E.DEPTNO
WHERE D.DEPTNO IN (10, 40)
ORDER BY D.DEPTNO, E.ENAME; DEPTNO DNAME ENAME
---------- -------------- ----------
10 ACCOUNTING CLARK
10 ACCOUNTING KING
10 ACCOUNTING MILLER
40 OPERATIONSE.DEPTNO(+) = D.DEPTNO.OUTER can be omitted. LEFT JOIN means the same thing.| ANSI | Oracle (+) | Side fully kept | Result rows for EMP and DEPT |
|---|---|---|---|
DEPT D LEFT JOIN EMP E ON D.DEPTNO = E.DEPTNO | E.DEPTNO(+) = D.DEPTNO | DEPT | 15 |
EMP E RIGHT JOIN DEPT D ON E.DEPTNO = D.DEPTNO | E.DEPTNO(+) = D.DEPTNO | DEPT | 15 |
EMP E FULL JOIN DEPT D ON E.DEPTNO = D.DEPTNO | Cannot be expressed | Both sides | 15 |
SELECT COUNT(*) FROM EMP E RIGHT OUTER JOIN DEPT D ON E.DEPTNO = D.DEPTNO; COUNT(*)
----------
15SELECT COUNT(*) FROM EMP E FULL OUTER JOIN DEPT D ON E.DEPTNO = D.DEPTNO; COUNT(*)
----------
15A LEFT JOIN B is B RIGHT JOIN A.Outer joins are also used to pick out only the rows without a match. The rows where the key on the NULL-filled side is NULL are the rows without a match.
SELECT D.DNAME FROM DEPT D LEFT JOIN EMP E ON D.DEPTNO = E.DEPTNO WHERE E.EMPNO IS NULL;DNAME
--------------
OPERATIONSANSI joins and (+) cannot be mixed in one query.
SELECT COUNT(*) FROM EMP E JOIN DEPT D ON E.DEPTNO = D.DEPTNO WHERE E.DEPTNO(+) = D.DEPTNO;SELECT COUNT(*) FROM EMP E JOIN DEPT D ON E.DEPTNO = D.DEPTNO WHERE E.DEPTNO(+) = D.DEPTNO
*
ERROR at line 1:
ORA-25156: old style outer join (+) cannot be used with ANSI joinsIn an INNER JOIN, the result is the same whether you put a condition in ON or in WHERE. In an outer join it is different. Here the situation is that you want to attach the employees with a salary of 3000 or more by department, but still show every department.
SELECT D.DNAME, E.ENAME, E.SAL
FROM DEPT D LEFT JOIN EMP E ON D.DEPTNO = E.DEPTNO AND E.SAL >= 3000
ORDER BY D.DNAME, E.ENAME;DNAME ENAME SAL
-------------- ---------- ----------
ACCOUNTING KING 5000
OPERATIONS
RESEARCH FORD 3000
RESEARCH SCOTT 3000
SALESSELECT D.DNAME, E.ENAME, E.SAL
FROM DEPT D LEFT JOIN EMP E ON D.DEPTNO = E.DEPTNO
WHERE E.SAL >= 3000
ORDER BY D.DNAME, E.ENAME;DNAME ENAME SAL
-------------- ---------- ----------
ACCOUNTING KING 5000
RESEARCH FORD 3000
RESEARCH SCOTT 3000| Condition position | When it is applied | Result |
|---|---|---|
| ON | When pairing. Only employees who meet the condition are accepted as a match | SALES and OPERATIONS, which have no match, are also kept with NULL (5 rows) |
| WHERE | It filters the result rows after the outer join is finished | The NULL rows drop out because NULL >= 3000 is not true (3 rows) |
(+) was left off E.SAL > 2900.⚠️ Trap: Conversely, if you put a condition on the kept side (DEPT) in ON, rows do not decrease.
ON D.DEPTNO = E.DEPTNO AND D.DEPTNO = 10means "only pair department 10 with employees". The other departments all remain in the result, and only the employee columns become NULL. To filter the rows of the kept side, write it in WHERE.
SELECT D.DNAME, E.ENAME
FROM DEPT D LEFT JOIN EMP E ON D.DEPTNO = E.DEPTNO AND D.DEPTNO = 10
ORDER BY D.DNAME, E.ENAME;DNAME ENAME
-------------- ----------
ACCOUNTING CLARK
ACCOUNTING KING
ACCOUNTING MILLER
OPERATIONS
RESEARCH
SALESSELECT D.DNAME, E.ENAME
FROM DEPT D LEFT JOIN EMP E ON D.DEPTNO = E.DEPTNO
WHERE D.DEPTNO = 10
ORDER BY D.DNAME, E.ENAME;DNAME ENAME
-------------- ----------
ACCOUNTING CLARK
ACCOUNTING KING
ACCOUNTING MILLERIf you GROUP BY the outer join result, you can even get the headcount of 0 for a department with no employees.
SELECT D.DNAME, COUNT(E.EMPNO) AS CNT
FROM DEPT D LEFT JOIN EMP E ON D.DEPTNO = E.DEPTNO
GROUP BY D.DNAME
ORDER BY D.DNAME;DNAME CNT
-------------- ----------
ACCOUNTING 3
OPERATIONS 0
RESEARCH 5
SALES 6Next week we cover subqueries, which put a query inside a query.
JOIN ... ON in the FROM clause.INNER can be omitted.(+).Click a choice to reveal the answer and explanation.
Question 1
Which is the correct result of running the following SQL in Oracle? ```sql SELECT E.ENAME, E.DEPTNO FROM EMP E NATURAL JOIN DEPT D; ```
Question 2
DEPT has 4 departments. CLERK is 1 person in department 10, 2 in department 20, and 1 in department 30, and department 40 has no employees. What is the result of the following SQL? ```sql SELECT COUNT(*) FROM DEPT D LEFT JOIN EMP E ON D.DEPTNO = E.DEPTNO AND E.JOB = 'CLERK'; ```
Question 3
Every employee in EMP belongs to a department that exists in DEPT, and DEPT 40 has no employees. What is the result of the following SQL? ```sql SELECT COUNT(*) FROM EMP E FULL OUTER JOIN DEPT D ON E.DEPTNO = D.DEPTNO; ```
Question 4
EMP and SALGRADE have no columns with the same name. EMP has 14 rows and SALGRADE has 5 rows. What is the result of the following SQL? ```sql SELECT COUNT(*) FROM EMP NATURAL JOIN SALGRADE; ```
Question 5
Which of the following causes an error when run in Oracle?