SQL Quick Reference
This page is a small companion page for SQL practice. It does not replace the course materials, but it is useful when you want to quickly recall the shape of a statement.
Read the Shape First
Before focusing on syntax, ask three small questions:
- What table or tables does the query start from?
- What does one result row represent?
- Which clauses are shaping the result?
That habit becomes especially useful once joins and grouped queries appear.
Basic Read Query
SELECT column1, column2
FROM table_name
WHERE condition
ORDER BY column1 ASC
LIMIT 10;
Common notes:
WHEREfilters rows.ORDER BYsorts rows.LIMITkeeps only the first part of the result.- Use
SELECT *mainly for exploration, not as the default teaching or maintenance style.
A More Concrete Read Query
SELECT name, email
FROM users
WHERE name ILIKE '%Ada%'
ORDER BY name
LIMIT 5;
A useful way to read this is:
- start from
users, - keep only rows whose
namematches the condition, - sort the remaining rows,
- and then keep at most five rows.
Checking for NULL
SELECT id, exercise_id, user_id
FROM submissions
WHERE score IS NULL;
Use IS NULL or IS NOT NULL, not = NULL.
Insert
INSERT INTO courses (code, title)
VALUES ('DB101', 'Introduction to Databases');
You can also insert several rows at once:
INSERT INTO courses (code, title)
VALUES
('DB101', 'Introduction to Databases'),
('DB102', 'Database Design');
Update
UPDATE courses
SET title = 'Databases and Data Management'
WHERE code = 'DB101';
Delete
DELETE FROM courses
WHERE code = 'DB101';
In a real schema, a delete like this may be rejected if other tables still reference the row through foreign keys.
Inner Join
SELECT e.title, c.code AS course_code, ci.term, ci.year
FROM exercises AS e
JOIN course_instances AS ci ON ci.id = e.course_instance_id
JOIN courses AS c ON c.id = ci.course_id;
Read joins as relationship paths. Ask which table you start from, what one result row represents, and which foreign-key path the query follows.
Left Join
SELECT c.code, ci.term, ci.year, e.title
FROM course_instances AS ci
INNER JOIN courses AS c ON c.id = ci.course_id
LEFT JOIN exercises AS e ON e.course_instance_id = ci.id
ORDER BY c.code, ci.year, ci.term;
Use a LEFT JOIN when rows from the left side should stay visible even if no matching row exists on the right side.
NOT EXISTS
SELECT u.name
FROM users AS u
WHERE NOT EXISTS (
SELECT 1
FROM submissions AS s
WHERE s.user_id = u.id
);
This pattern is useful when the question is about missing related rows, such as users with no submissions.
Grouping and Aggregation
SELECT exercise_id, COUNT(*) AS submission_count
FROM submissions
GROUP BY exercise_id
HAVING COUNT(*) >= 5;
Common notes:
WHEREfilters rows before grouping.HAVINGfilters grouped results after grouping.- Always ask what one grouped row represents.
Set Operations
SELECT user_id
FROM submissions
WHERE score >= 50
UNION
SELECT user_id
FROM enrollments;
With UNION, the result sets must have compatible columns. The result combines the rows and removes duplicates.
Create Table
CREATE TABLE courses (
id SERIAL PRIMARY KEY,
code TEXT NOT NULL UNIQUE,
title TEXT NOT NULL
);
Add a Foreign Key
CREATE TABLE exercises (
id SERIAL PRIMARY KEY,
course_instance_id INTEGER NOT NULL REFERENCES course_instances(id),
title TEXT NOT NULL
);
This is a common pattern in the course: one table stores a foreign key that points to another table.
Clause Order at a Glance
The common written order of a query is:
SELECT ...
FROM ...
WHERE ...
GROUP BY ...
HAVING ...
ORDER BY ...
LIMIT ...
This is worth remembering because many common mistakes come from mixing up:
- row filtering with
WHERE, - group filtering with
HAVING, - and result ordering with
ORDER BY.
Parameterized Query in Application Code
In the application parts of the course, values should be passed separately from the SQL structure. With Psycopg t-strings, a safe pattern looks like this:
conn.execute(t"""
INSERT INTO tags (name)
VALUES ({name})
""")
The important idea is that user input should not be pasted directly into the SQL text.
Safe SQL Habits
- Start from the question, not from random syntax.
- Read the table or schema before writing the query.
- For
UPDATEandDELETE, run a matchingSELECTfirst. - After write queries, verify the new database state.
- Prefer parameterized queries in application code.
- Keep one eye on meaning: what does one result row represent?