A3.3.2 · Database programming
Constructing queries between two tables
A single table can only ever answer questions about itself, the moment a question needs "which artist played which concert," two tables have to be brought together in one query.
Explainer
A3.3.1 introduced SELECT as one of the DML statements. This statement is about everything SELECT can actually DO once two tables are involved: combining them, filtering what comes back, matching text patterns, and putting the results in a sensible order.
A JOIN combines rows from two tables based on a matching column between them, usually a primary key in one table and the matching foreign key in the other. Without it, a query can only ever see one table at a time.
How a JOIN actually builds its result
Not by magic, by checking one ID at a time against the other table, over and over.
The command toolkit
| Command | What it does | Example |
|---|---|---|
| JOIN ... ON ... | Combines rows from two tables using a matching column. | SELECT * FROM Concert JOIN Artist ON Concert.ArtistID = Artist.ArtistID; |
| DISTINCT | Removes duplicate rows from the result, keeping only unique ones. | SELECT DISTINCT Genre FROM Artist; |
| WHERE | Filters individual rows before any grouping happens. | SELECT * FROM Concert WHERE VenueName = "Blue Note Club"; |
| = <> > < >= <= | Relational operators: compare a field's value against a given value. | SELECT * FROM Concert WHERE TicketPrice > 50; |
| BETWEEN ... AND ... | Filters values that fall within a range. | SELECT * FROM Concert WHERE TicketPrice BETWEEN 40 AND 80; |
| LIKE, with % and _ | Matches text against a pattern instead of an exact value. % stands in for any run of characters, however long, while _ stands in for one character and one only. | SELECT * FROM Concert WHERE VenueName LIKE "%Club"; |
| AND, OR, NOT | Combines or negates multiple conditions in a WHERE clause. | SELECT * FROM Concert WHERE TicketPrice > 50 AND NOT VenueName = "Grand Arena"; |
| ORDER BY ... ASC / DESC | Sorts the result, ascending or descending, by one or more fields. | SELECT * FROM Concert ORDER BY TicketPrice DESC; |
| GROUP BY | Collapses rows sharing a value into groups. | SELECT VenueName, COUNT(*) FROM Concert GROUP BY VenueName; |
| HAVING | Filters GROUPS after they've been formed, unlike WHERE, which filters rows before grouping. | SELECT VenueName, COUNT(*) FROM Concert GROUP BY VenueName HAVING COUNT(*) > 1; |
Worked example
ARTIST and CONCERT: one command at a time
Two tables, ARTIST and CONCERT, linked by ArtistID. Click through and watch the same two tables answer a different question at every step.
Try it yourself
Run your own queries
The same ARTIST and CONCERT tables, live. The command term for this statement is construct, and constructing means writing one yourself, not recognising one someone else wrote. Everything A3.3 teaches works here, not only this statement's own commands, so INSERT, UPDATE and DELETE run too and really do change the tables until you reset them.
4 rows
5 rows
Things worth trying. Write ArtistID on its own in a joined query and see why it has to be qualified. Swap HAVING for WHERE in the last example. Change LIKE "Dana%" to LIKE "%s" and work out why the results change. Each one is a real exam error, and triggering it yourself makes it stick.
Check your understanding
A query needs to find only the venues that have hosted MORE THAN ONE concert. Which clause makes that filter possible?
Common mistake
A3.3.2RecurringWHERE and HAVING both look like they "filter the query," and candidates often use them interchangeably. WHERE filters ROWS, before any grouping exists. HAVING filters GROUPS, after GROUP BY has already run, and it's the only one of the two that can reference an aggregate like COUNT(*) at all.
What a weak answer looks like: "WHERE COUNT(*) > 1" to find venues with more than one concert. This is invalid, COUNT(*) doesn't exist yet at the point WHERE runs, grouping hasn't happened.
What it should say: "GROUP BY VenueName HAVING COUNT(*) > 1", group the rows by venue first, THEN filter which groups survive based on how many rows ended up in each one.
Linking question
How do programming languages interact with databases to store, retrieve and manipulate data?
A JOIN query like the ones on this page rarely runs on its own, a real application embeds it inside Python, Java or another high-level language, which sends the SQL string to the database, waits for the result set, then loops over it like any other collection. The SQL itself stays declarative (WHAT to retrieve), the surrounding program stays imperative (HOW to use what comes back).
Revision questions
Past-paper style. Write an answer, then reveal the marking points and mark yourself.
[2]Construct a query that joins ARTIST and CONCERT to list every artist's name alongside the venue they played.
Marking points
评分要点
- A correct SELECT naming the two columns, for example Artist.Name and Concert.Venue.
- FROM Artist JOIN Concert ON Artist.ArtistID = Concert.ArtistID (foreign key matched to primary key).
- 一条正确的 SELECT,写出两个列,例如 Artist.Name 和 Concert.Venue。
- FROM Artist JOIN Concert ON Artist.ArtistID = Concert.ArtistID(外键匹配主键)。
[3]Construct a query that finds every artist whose name starts with "The".
Marking points
评分要点
- SELECT * FROM Artist (or the name column).
- WHERE Name LIKE 'The%'.
- The % wildcard matches any characters after The, so every name beginning with The is returned.
- SELECT * FROM Artist(或选姓名列)。
- WHERE Name LIKE 'The%'。
- 通配符 % 匹配 The 之后的任意字符,所以每个以 The 开头的名字都会被返回。
[5]Construct a query that lists every concert with a TicketPrice between 40 and 80, ordered by TicketPrice in descending order. Explain why BETWEEN is inclusive of both boundary values.
Marking points
评分要点
- SELECT the concert rows FROM Concert.
- WHERE TicketPrice BETWEEN 40 AND 80.
- ORDER BY TicketPrice DESC.
- BETWEEN is inclusive because it is defined as TicketPrice >= 40 AND TicketPrice <= 80, so 40 and 80 both qualify.
- 从 Concert 表 SELECT 演出行。
- WHERE TicketPrice BETWEEN 40 AND 80。
- ORDER BY TicketPrice DESC。
- BETWEEN 包含端点,因为它被定义为 TicketPrice >= 40 AND TicketPrice <= 80,所以 40 和 80 都满足。
Flashcards
Active recall for this statement's key terms.
Keep this statement's practice with you
Free account: unlock every revision question and flashcard for A3.3.2, and every other IB CS 2027 statement.