🚧 Under construction — VoTechWorks is being built. A free tech program — complimentary, as our commitment to get America working.
voTechWorksGrade 13 · a vocational technology learning center, by urbanicity
newSchoolWorks.com › VoTechWorks › Technology & Design › Data Science & Analytics › SQL and PostgreSQL for Data Analytics › Lesson 4
TEC-DATA85-04 · Lesson 4 · 12 clock hours · lab

Joining Tables and Data Modeling

Objective. Students design a two-to-four table normalized schema from a business scenario and execute INNER, LEFT, RIGHT, and FULL OUTER JOIN queries correctly.

⚠ Pending professional review

This lesson, its worked examples and its practice questions has not yet been verified by an industry-certified professional or by a certification or approval body. It is a study draft and may contain errors. Do not use it as instructions for work on a job site or on live equipment. Always follow your instructor, your supervising professional, and current official references and regulations.

VoTechWorks program approval and accreditation are still in progress. Credentials are issued only by the certifying bodies named in each program, after their own exams.

Why Joins and Data Modeling Matter

Real business data rarely lives in a single table. A permits office tracks applicants, contractors, permit types, and inspections — all separate ideas that relate to one another. Relational databases store each idea in its own table and use keys to connect them. Knowing how to design those tables well and query across them is a foundational skill tested on CompTIA Data+, Google Data Analytics, and the IBM Data Science Professional certificate.

Normalization: Designing Tables That Hold Together

Normalization is the process of organizing columns and tables to reduce redundant data and prevent update anomalies. For this course, focus on two key rules:

The result is a schema where each fact is stored once. Changing a contractor's phone number means updating one row in one table, not hunting through thousands of permit records.

Entity-Relationship Diagrams

Before writing any SQL, draw an entity-relationship (ER) diagram. An ER diagram shows:

Draw the diagram on paper first. Instructors review diagrams before students write SQL because fixing a design flaw on paper takes seconds; fixing it after tables are loaded takes much longer.

Primary Keys and Foreign Keys

A primary key (PK) uniquely identifies each row. Choose a surrogate key (a serial integer or UUID generated by the database) when no natural column is reliably unique.

A foreign key (FK) is a column in one table whose values must match a primary key value in another table — or be NULL. PostgreSQL enforces this with the `REFERENCES` keyword. If you try to insert a permit row that references a contractor_id that does not exist, the database rejects the insert. This constraint protects data integrity automatically.

```sql

CREATE TABLE contractor (

contractor_id SERIAL PRIMARY KEY,

company_name VARCHAR(120) NOT NULL,

license_number VARCHAR(30) UNIQUE NOT NULL,

phone VARCHAR(20)

);

CREATE TABLE permit (

permit_id SERIAL PRIMARY KEY,

permit_type_id INT REFERENCES permit_type(permit_type_id),

contractor_id INT REFERENCES contractor(contractor_id), -- NULL allowed

issue_date DATE NOT NULL,

status VARCHAR(20) NOT NULL

);

```

Notice that `contractor_id` in the permit table allows NULL. A permit may be filed by an individual homeowner with no licensed contractor. This design choice drives the LEFT JOIN example below.

The Four JOIN Types

INNER JOIN returns only rows where the join condition matches in both tables. Permits with no contractor and contractors with no permits are both excluded.

LEFT JOIN (LEFT OUTER JOIN) returns all rows from the left table and matching rows from the right. Non-matching right-side columns are NULL. Use this to find permits that have no associated contractor.

RIGHT JOIN (RIGHT OUTER JOIN) returns all rows from the right table and matching rows from the left. Less common; you can always rewrite a RIGHT JOIN as a LEFT JOIN by swapping table order.

FULL OUTER JOIN returns all rows from both tables; unmatched sides are NULL. Use this when you need a complete picture — every permit and every contractor, matched where possible.

```sql

-- INNER JOIN: permits with a known contractor

SELECT p.permit_id, p.issue_date, c.company_name

FROM permit p

INNER JOIN contractor c ON p.contractor_id = c.contractor_id;

-- LEFT JOIN: all permits, contractor name or NULL

SELECT p.permit_id, p.status, c.company_name

FROM permit p

LEFT JOIN contractor c ON p.contractor_id = c.contractor_id;

-- Filter to permits with NO contractor

SELECT p.permit_id, p.status

FROM permit p

LEFT JOIN contractor c ON p.contractor_id = c.contractor_id

WHERE c.contractor_id IS NULL;

```

Exporting Results as CSV in pgAdmin 4

After running a query in pgAdmin 4, use File → Download as CSV from the query results panel to save the output. Keep exported files named clearly (for example, `query3_unmatched_permits.csv`). This is the format your instructor will verify.

Data Integrity and Safe Practices

Although data analytics work does not involve physical hazards, good data practice has its own safety rules:

What the Grader Checks

The instructor compares your query output row-for-row against a reference database loaded with the same sample data. Seven of your eight JOIN queries must return the correct result set. Pay attention to NULLs — an INNER JOIN and a LEFT JOIN on the same tables return different row counts, and that difference is exactly what is being tested.

Key terms8

NormalizationThe process of organizing database tables so that each fact is stored once, repeating groups are eliminated, and every non-key column depends on the primary key.
Primary key (PK)A column or set of columns that uniquely identifies every row in a table; no two rows may share the same primary key value.
Foreign key (FK)A column in one table whose values must match a primary key value in a related table, enforcing referential integrity between tables.
Entity-relationship (ER) diagramA visual map showing the entities (tables), their attributes (columns), and the relationships and cardinality between them, drawn before any SQL is written.
INNER JOINA JOIN that returns only the rows where the join condition is satisfied in both tables; unmatched rows from either table are excluded.
LEFT JOINA JOIN that returns all rows from the left table and the matching rows from the right table; unmatched right-side columns appear as NULL.
FULL OUTER JOINA JOIN that returns all rows from both tables, with NULLs filling in for unmatched columns on either side.
Referential integrityThe guarantee that a foreign key value always points to an existing primary key value (or is NULL if permitted), enforced automatically by the database engine.
In class: Schema design workshop: each student receives a written scenario (a small municipal permits office) and draws an entity-relationship diagram on paper, identifying tables, columns, and key relationships; instructor reviews diagrams before students write any SQL. · DDL implementation: students translate their ER diagram into CREATE TABLE statements with correct data types and REFERENCES constraints, then insert 20 rows of sample data using INSERT statements. · JOIN query set: students write eight queries across the permits schema that require at least one JOIN each, including at least one LEFT JOIN that surfaces permits with no associated contractor, saving results as CSV exports.
Materials: PostgreSQL 16 / pgAdmin 4, printed scenario handout, ER-diagram paper templates, draw.io (free tier) for digital ER diagrams, PostgreSQL documentation chapter on DDL
Check: Instructor evaluates ER diagram for correct normalization (no repeating groups, all non-key columns depending on the primary key) and runs the eight JOIN queries against a reference database; 7 of 8 queries must return the correct result set to pass.

Practice check8

Answer each question, then check it. Nothing is recorded; this is your own practice.

Data Analysis Concepts and Principles (CompTIA Data+)
1. A student adds the following column to the permit table: `contractor_phone VARCHAR(20)`. The contractor's phone number is already stored in the contractor table. Which normalization problem does this create?
Databases and Data Acquisition (CompTIA Data+)
2. Which SQL JOIN type should you use when you want every row from the permit table, including permits that have no matching row in the contractor table?
Databases and Data Acquisition (CompTIA Data+)
3. A student writes `FROM permit p INNER JOIN contractor c ON p.contractor_id = c.contractor_id` and gets 45 rows. She then changes INNER to LEFT and gets 52 rows. What does the difference of 7 rows represent?
Databases and Data Acquisition (CompTIA Data+)
4. In PostgreSQL, which DDL clause enforces that the value in `permit.contractor_id` must match an existing value in `contractor.contractor_id`?
Databases and Data Acquisition (CompTIA Data+)
5. A FULL OUTER JOIN between the permit table (60 rows) and the inspection table (80 rows) returns 95 rows. What is the most likely explanation?
Data Governance and Quality (CompTIA Data+)
6. Before executing CREATE TABLE statements on a shared PostgreSQL server in this lab, best practice is to:
Data Analysis Concepts and Principles (Google Data Analytics)
7. In the Google Data Analytics framework, the step that most directly corresponds to writing JOIN queries to combine data from multiple tables is:
Databases and Data Acquisition (CompTIA Data+)
8. A student wants to identify which contractors have never been assigned to any permit. Which query structure correctly returns only those contractors?
Record this lesson on my transcript. Sign in with your key and enrollment email to record lessons (enroll free if you have no key). This page stays open to read and practise.