DBMS slides 📂 Introduction · 10 of 11 42 min read

Set Operators, Views, Indexes & Joins in SQL

A 16-slide visual guide to four core SQL tools. It covers set operators (UNION, UNION ALL, INTERSECT, EXCEPT/MINUS) and union-compatibility, every join type (INNER, LEFT, RIGHT, FULL OUTER, SELF), views (virtual vs materialized) and indexes (B-tree seek vs full scan, the left-prefix rule) — with animated Venn, join-link, view and index diagrams.

Set Operators, Views, Indexes & Joins in SQL

Stack rows with set operators, widen them with joins, hide complexity behind views, and make it all fast with indexes — the four tools that turn plain SELECTs into real database power.
UNION · INTERSECT · EXCEPT Views Indexes Joins

Press Next → or use ← → arrow keys

Section 01

The Story — Two Guest Lists, One Wedding

Combining, comparing and subtracting lists
The bride and groom each hand you a guest list. UNION merges them without inviting anyone twice. INTERSECT finds the people on both lists — friends of the whole couple. EXCEPT finds who's on one list but not the other. That's the entire idea of set operators.
🧭
Set Operators vs Joins — the One-Line Difference

Set operators stack results vertically (row on row, same columns). Joins stitch results horizontally (columns from one table beside another, matched by a key).

Section 02

The Sample Database

online_buyers

idname
1Asha
2Bilal
3Chen
4Diya

store_buyers

idname
3Chen
4Diya
5Esha
6Farid

employees

idnamedeptmgrsal
101Asha10NULL95k
102Bilal1010162k
103Chen2010158k
104Diya3010247k
105EshaNULL10251k

departments

deptname
10Engineering
20Sales
30Marketing
40Research ← 0 staff
🕳️
Gaps Planted on Purpose

Asha's NULL manager, Esha's NULL dept, and Research with no employees — these expose exactly how INNER and OUTER joins differ.

Section 03

Set Operators — The Venn Picture

UNION both, no dupes UNION ALL both, keep dupes INTERSECT only the overlap EXCEPT left minus right ● online_buyers (1,2,3,4) ● store_buyers (3,4,5,6)
↔️
EXCEPT Is Directional — UNION & INTERSECT Are Not

Swap the two queries around UNION or INTERSECT and the answer is identical. Swap them around EXCEPT and you get a completely different set. Read EXCEPT as "keep the left, subtract the right."

Section 04–06

UNION · INTERSECT · EXCEPT in Action

SELECT cust_id, name FROM online_buyers
UNION
SELECT cust_id, name FROM store_buyers
ORDER BY cust_id;
UNION → all six, deduped
1 Asha · 2 Bilal · 3 Chen 4 Diya · 5 Esha · 6 Farid
SELECT cust_id, name FROM online_buyers
INTERSECT
SELECT cust_id, name FROM store_buyers;
INTERSECT → in both
3 Chen · 4 Diya
SELECT cust_id, name FROM online_buyers
EXCEPT
SELECT cust_id, name FROM store_buyers;
online EXCEPT store
1 Asha · 2 Bilal
store EXCEPT online (reversed!)
5 Esha · 6 Farid
🔤
Oracle says MINUS

Oracle uses MINUS where standard SQL uses EXCEPT — same meaning.

Section 07

Set Operator Rules at a Glance

OperatorReturnsRemoves dupes?Order matters?Oracle
UNIONAll rows from bothYesNoUNION
UNION ALLAll rows from bothNoNoUNION ALL
INTERSECTRows in bothYesNoINTERSECT
EXCEPTLeft minus rightYesYesMINUS
✅ THE FOUR NON-NEGOTIABLE REQUIREMENTS (union-compatible)
1
Both queries return the same number of columns.
2
Corresponding columns have compatible data types.
3
Column names come from the first query; the rest are ignored.
4
A single ORDER BY goes last, applying to the whole result.
Prefer UNION ALL When You Can

If duplicates are impossible or wanted, UNION ALL skips the expensive dedup pass — measurably faster.

Section 08

Views — A Saved Query That Acts Like a Table

A view is a window onto your data, not a copy. You name a query once; every SELECT from the view runs it fresh against the live base tables.

employees departments base tables — data physically stored VIEW: staff_dirsvirtual · runs live, stores nothing
CREATE VIEW staff_dirs AS
  SELECT e.name, d.dept_name, e.salary
  FROM employees e JOIN departments d ON e.dept_id = d.dept_id;

SELECT name, dept_name FROM staff_dirs WHERE salary > 50000;   -- query it like a table
🔐
Why views

Security (expose safe columns), simplicity (wrap a complex join), consistency (one definition, one source of truth).

💾
Standard vs Materialized

Standard = stores nothing, always fresh. Materialized = stores the result, must refresh — trades freshness for speed.

Section 09

Indexes — The Speed Mechanism

An index is the index at the back of a textbook: instead of reading all 900 pages, you jump straight to the right one. The engine uses a sorted B-tree instead of scanning every row.

Full table scan — O(n) id=1 id=2 id=3 id=4 ✓ checks every row until it finds id = 4 Index seek — O(log n) B-tree root 1–3 4–6 id=4 ✓ jumps straight to id = 4
CREATE INDEX idx_emp_dept ON employees(dept_id);              -- simple
CREATE INDEX idx_emp_dept_sal ON employees(dept_id, salary);  -- composite
CREATE UNIQUE INDEX idx_emp_email ON employees(email);       -- unique
Section 09 · Trade-offs

Indexes Are Not Free

When indexes help
WHERE filtering · JOIN keys · ORDER BY / GROUP BY · high-selectivity columns (many distinct values).
When indexes hurt
Heavy INSERT/UPDATE load · tiny tables · low-selectivity columns (e.g. gender) · rarely-queried columns.
💸
Every Index Has a Cost

Each index must be updated on every INSERT, UPDATE and DELETE, and it eats disk. Indexing every column "to be safe" slows writes and wastes storage — index what you filter, join, or sort on.

🧩
The Left-Prefix Rule

An index on (dept_id, salary) serves queries on dept_id alone ✓ and dept_id AND salary ✓ — but salary alone ✗. The leftmost column must be used.

Section 10

Joins — Stitching Tables Side by Side

A join matches rows from two tables on a related column and merges them into one wider row. Four flavours differ only in which unmatched rows they keep.

INNERmatches only LEFTall left + match RIGHTall right + match FULL OUTEReverything
🔍
Find the Orphans

To find rows with no match — departments with no employees, customers with no orders — LEFT JOIN then filter WHERE right.key IS NULL.

Section 11

INNER JOIN — Only Matching Rows

employees.dept_id departments.dept_id Asha · 10 Bilal · 10 Chen · 20 Diya · 30 Esha · NULL 10 Engineering 20 Sales 30 Marketing 40 Research
SELECT e.name, d.dept_name
FROM employees e INNER JOIN departments d ON e.dept_id = d.dept_id;
-- Asha·Eng, Bilal·Eng, Chen·Sales, Diya·Marketing  (Esha & Research dropped)
🔗
Match on Both Sides, or Drop

Esha's NULL dept has nothing to match; Research has no employees. INNER JOIN keeps only the solid green links.

Section 12

OUTER JOINs — Keep the Unmatched

Outer joins preserve rows with no match, filling the missing side with NULL.

-- LEFT: all employees, dept if any
SELECT e.name, d.dept_name
FROM employees e
LEFT JOIN departments d
  ON e.dept_id = d.dept_id;
LEFT result
Asha Engineering Bilal Engineering Chen Sales Diya Marketing Esha NULL ← kept
-- RIGHT: all departments, staff if any
SELECT e.name, d.dept_name
FROM employees e
RIGHT JOIN departments d
  ON e.dept_id = d.dept_id;
RIGHT result
Asha Engineering Bilal Engineering Chen Sales Diya Marketing NULL Research ← kept
🧭
FULL OUTER = Both at Once

FULL OUTER JOIN keeps every row from both sides, NULL-filling wherever a match is missing on either side — Esha and Research both survive.

Section 13

SELF JOIN — A Table Joined to Itself

A manager is an employee — manager_id points to another emp_id in the same table. So the table plays two roles at once.

e — worker m — manager Bilal · mgr 101 Chen · mgr 101 Diya · mgr 102 101 · Asha 102 · Bilal e.manager_id = m.emp_id
SELECT e.name AS employee, m.name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.emp_id;
-- Asha→NULL, Bilal→Asha, Chen→Asha, Diya→Bilal, Esha→Bilal
🏷️
Aliases Are Mandatory

Because the same table appears twice, each instance needs a distinct alias (e, m) — otherwise the database can't tell which copy a column means.

Section 14

Joins vs Set Operators — Side by Side

PropertySet OperatorsJoins
DirectionVertical — stack rowsHorizontal — widen rows
ColumnsSame count & types both sidesAny columns; matched on a key
Result widthSame as input columnsSum of both tables' columns
Matches onWhole-row equalityA specified ON condition
Typical question"In which list(s)?""What related detail?"
🧱
Two Different Shapes of Combination

Set operators answer membership ("who's on which list?"); joins answer relationship ("what detail connects to this row?").

Section 16

Golden Rules

🏆 NON-NEGOTIABLE RULES
1
Union-compatible: set operators need the same column count, order and compatible types; names come from the first query.
2
Prefer UNION ALL over UNION when duplicates are impossible or wanted — it skips the dedup step.
3
EXCEPT is directional (UNION and INTERSECT are not). Read it as "keep the left, subtract the right."
4
Views are virtual — no stored data, re-run live. Use a materialized view only to cache an expensive result.
5
Index strategically — the columns you filter, join or sort on, not every column. Indexes speed reads but slow writes.
6
Left-prefix rule: a composite index on (a, b) helps queries on a or a AND b — never b alone.
7
Join types: INNER keeps matches; LEFT/RIGHT keep one whole side; FULL keeps all. Orphans = LEFT JOIN + WHERE right.key IS NULL.
8
Self joins need two aliases — the same table is referenced twice in one statement.
FINAL

Four Tools, One Toolbox

4Set operators
5Join types (+ self)
2View kinds
O(log n)Index seek speed
🎯
The Foundation Is Set

You can now stack rows with set operators, widen them with any join, hide complexity behind a view, and accelerate lookups with the right index — while dodging the union-compatibility, EXCEPT-direction and left-prefix traps. Next up: transactions, concurrency and ACID.

🧠
One Sentence to Remember

Set operators stack rows vertically; joins widen rows horizontally; views hide the query; indexes skip the scan.

🔗 End of tutorial · Press to review, or click Restart