Many-to-many relationships let us connect items from two groups where each item can link to many from the other group. Junction tables help organize these links clearly.
Many-to-many with junction tables in SQL
Start learning this pattern below
Jump into concepts and practice - no test required
or
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Syntax
SQL
CREATE TABLE TableA ( id INT PRIMARY KEY, name VARCHAR(100) ); CREATE TABLE TableB ( id INT PRIMARY KEY, description VARCHAR(100) ); CREATE TABLE JunctionTable ( tableA_id INT, tableB_id INT, PRIMARY KEY (tableA_id, tableB_id), FOREIGN KEY (tableA_id) REFERENCES TableA(id), FOREIGN KEY (tableB_id) REFERENCES TableB(id) );
The junction table holds pairs of IDs from the two tables to link them.
Primary key on both columns prevents duplicate links.
Examples
SQL
CREATE TABLE Students ( student_id INT PRIMARY KEY, student_name VARCHAR(50) ); CREATE TABLE Courses ( course_id INT PRIMARY KEY, course_name VARCHAR(50) ); CREATE TABLE Enrollments ( student_id INT, course_id INT, PRIMARY KEY (student_id, course_id), FOREIGN KEY (student_id) REFERENCES Students(student_id), FOREIGN KEY (course_id) REFERENCES Courses(course_id) );
SQL
CREATE TABLE Authors ( author_id INT PRIMARY KEY, author_name VARCHAR(50) ); CREATE TABLE Books ( book_id INT PRIMARY KEY, book_title VARCHAR(100) ); CREATE TABLE AuthorBook ( author_id INT, book_id INT, PRIMARY KEY (author_id, book_id), FOREIGN KEY (author_id) REFERENCES Authors(author_id), FOREIGN KEY (book_id) REFERENCES Books(book_id) );
Sample Program
This query shows which students are enrolled in which courses using the junction table.
SQL
CREATE TABLE Students ( student_id INT PRIMARY KEY, student_name VARCHAR(50) ); CREATE TABLE Courses ( course_id INT PRIMARY KEY, course_name VARCHAR(50) ); CREATE TABLE Enrollments ( student_id INT, course_id INT, PRIMARY KEY (student_id, course_id), FOREIGN KEY (student_id) REFERENCES Students(student_id), FOREIGN KEY (course_id) REFERENCES Courses(course_id) ); INSERT INTO Students VALUES (1, 'Alice'), (2, 'Bob'); INSERT INTO Courses VALUES (101, 'Math'), (102, 'History'); INSERT INTO Enrollments VALUES (1, 101), (1, 102), (2, 101); SELECT s.student_name, c.course_name FROM Enrollments e JOIN Students s ON e.student_id = s.student_id JOIN Courses c ON e.course_id = c.course_id ORDER BY s.student_name, c.course_name;
Important Notes
Always use foreign keys in the junction table to keep data linked correctly.
Composite primary key in the junction table avoids duplicate pairs.
You can add extra columns in the junction table for details about the relationship, like enrollment date.
Summary
Many-to-many relationships connect items from two tables in pairs.
Junction tables store these pairs with foreign keys to both tables.
This setup keeps data organized and easy to query.
Practice
1. What is the main purpose of a junction table in a many-to-many relationship?
easy
Solution
Step 1: Understand many-to-many relationships
Many-to-many means each record in one table can relate to many records in another table, and vice versa.Step 2: Role of junction table
A junction table holds pairs of foreign keys from both tables to link related records without duplicating data.Final Answer:
To store pairs of related records from two tables using foreign keys -> Option AQuick Check:
Junction table = pairs of foreign keys [OK]
Hint: Junction tables link two tables with pairs of keys [OK]
Common Mistakes:
- Thinking junction table stores all data from both tables
- Confusing junction table with a single main table
- Assuming junction table creates one-to-one links
2. Which SQL statement correctly creates a junction table named
StudentCourse linking Student and Course tables by their IDs?easy
Solution
Step 1: Define junction table columns
It needs two columns for foreign keys: StudentID and CourseID.Step 2: Set primary key on both columns
Primary key on (StudentID, CourseID) ensures unique pairs and no duplicates.Final Answer:
CREATE TABLE StudentCourse (StudentID INT, CourseID INT, PRIMARY KEY (StudentID, CourseID)); -> Option DQuick Check:
Junction table needs composite primary key [OK]
Hint: Use composite primary key on both foreign keys [OK]
Common Mistakes:
- Using UNIQUE on individual columns instead of composite key
- Missing one foreign key column
- Not defining primary key on the pair
3. Given tables
Author, Book, and junction table AuthorBook with columns AuthorID and BookID, what does this query return?SELECT Author.Name, Book.Title FROM Author
JOIN AuthorBook ON Author.ID = AuthorBook.AuthorID
JOIN Book ON Book.ID = AuthorBook.BookID;
medium
Solution
Step 1: Understand JOINs with junction table
The query joins Author to AuthorBook by AuthorID, then AuthorBook to Book by BookID, linking authors to their books.Step 2: Result of the query
It returns pairs of author names and book titles where the author wrote the book, no unrelated pairs included.Final Answer:
A list of authors and the titles of books they wrote -> Option AQuick Check:
JOINs with junction table = related pairs only [OK]
Hint: JOIN junction table to get related pairs only [OK]
Common Mistakes:
- Thinking it returns all combinations of authors and books
- Expecting an error without WHERE clause
- Ignoring the role of junction table in filtering
4. You wrote this query to find all students and their courses:
But it has a problem. What is the problem?
SELECT Student.Name, Course.Title FROM Student
JOIN StudentCourse ON Student.ID = StudentCourse.StudentID
JOIN Course ON Course.ID = StudentCourse.CourseID
WHERE StudentCourse.StudentID = Student.ID;
But it has a problem. What is the problem?
medium
Solution
Step 1: Analyze the JOIN conditions
The JOINs already match Student.ID to StudentCourse.StudentID and Course.ID to StudentCourse.CourseID.Step 2: Check the WHERE clause
The WHERE clause repeats the JOIN condition, which is unnecessary but not an error; however, it does not filter or add value.Final Answer:
The WHERE clause is unnecessary because JOIN already matches IDs -> Option CQuick Check:
JOIN matches IDs, WHERE clause redundant [OK]
Hint: JOIN conditions handle matching; WHERE often not needed here [OK]
Common Mistakes:
- Assuming WHERE clause causes syntax error
- Adding unnecessary conditions that duplicate JOINs
- Confusing alias usage with errors
5. You have tables
Employee, Project, and junction table EmployeeProject with EmployeeID and ProjectID. How do you find employees who work on all projects listed in Project?hard
Solution
Step 1: Count total projects
Find total number of projects from Project table.Step 2: Group EmployeeProject by EmployeeID
Count how many projects each employee works on.Step 3: Use HAVING to compare counts
Only select employees whose project count equals total projects count.Final Answer:
Use GROUP BY EmployeeID and HAVING count of projects equal to total projects count -> Option BQuick Check:
Group and count projects per employee = all projects [OK]
Hint: Group by employee, HAVING count = total projects [OK]
Common Mistakes:
- Not grouping and counting projects per employee
- Using WHERE instead of HAVING for aggregate filtering
- Ignoring total projects count in comparison
