二元关系操作:JOIN 和 DIVISION
在关系数据库中,JOIN 和 DIVISION 都是常用的操作。JOIN 操作允许我们将两个或多个表中的信息联合起来,而 DIVISION 允许我们从一个表中查找满足一组条件的所有元组。在本文中,我们将详细介绍这两种操作。
阅读更多:MySQL 教程
JOIN 操作
在 SQL 中,JOIN 操作用于合并两个或多个表的信息。JOIN 操作可以有多种类型:
- INNER JOIN:只返回两个表中至少有一行匹配的行
- LEFT JOIN:返回两个表中所有左表(前面表)中的行以及右表(后面表)中至少有一行匹配的行
- RIGHT JOIN:返回两个表中所有右表(后面表)中的行以及左表(前面表)中至少有一行匹配的行
- FULL OUTER JOIN:返回两个表中所有行,如果其中一个表没有匹配的行,则相应的列将包含 NULL 值
下面是一个使用 INNER JOIN 的例子。假设我们有两个表:学生表(students
)和课程表(courses
)。学生表包含学生的姓名和 ID,课程表包含课程名称和 ID,还有每个学生已经完成的课程 ID。
CREATE TABLE students (
id INTEGER PRIMARY KEY,
name VARCHAR(50) NOT NULL
);
CREATE TABLE courses (
id INTEGER PRIMARY KEY,
name VARCHAR(50) NOT NULL
);
CREATE TABLE student_courses (
student_id INTEGER NOT NULL,
course_id INTEGER NOT NULL,
FOREIGN KEY (student_id) REFERENCES students(id),
FOREIGN KEY (course_id) REFERENCES courses(id)
);
INSERT INTO students (id, name) VALUES (1, 'Alice');
INSERT INTO students (id, name) VALUES (2, 'Bob');
INSERT INTO students (id, name) VALUES (3, 'Charlie');
INSERT INTO courses (id, name) VALUES (1, 'Database Systems');
INSERT INTO courses (id, name) VALUES (2, 'Computer Networks');
INSERT INTO courses (id, name) VALUES (3, 'Algorithms');
INSERT INTO student_courses (student_id, course_id) VALUES (1, 1);
INSERT INTO student_courses (student_id, course_id) VALUES (1, 2);
INSERT INTO student_courses (student_id, course_id) VALUES (2, 1);
INSERT INTO student_courses (student_id, course_id) VALUES (2, 3);
INSERT INTO student_courses (student_id, course_id) VALUES (3, 2);
我们想要列出每个学生所完成的课程名称,可以使用 INNER JOIN:
SELECT students.name, courses.name
FROM students
INNER JOIN student_courses ON students.id = student_courses.student_id
INNER JOIN courses ON student_courses.course_id = courses.id;
这将会返回以下结果:
name | name
--------+----------------------
Alice | Database Systems
Alice | Computer Networks
Bob | Database Systems
Bob | Algorithms
Charlie | Computer Networks
DIVISION 操作
DIVISION 操作用于查找满足一组条件的所有元组。假设我们有一个表 R(A, B)
,还有一个表 S(B)
,我们想要查找在表 R
中每个 A
值都有对应的 B
值,且这些 B
值都在表 S
中出现过的 A
值,可以使用 DIVISION 操作。
以下是一个使用 DIVISION 操作的例子。假设我们有三个表:学生表(students
),课程表(courses
)和已注册课程表(registrations
),其中已注册课程表列出每个学生已经注册的课程:
CREATE TABLE students (
id INTEGER PRIMARY KEY,
name VARCHAR(50) NOT NULL
);
CREATE TABLE courses (
id INTEGER PRIMARY KEY,
name VARCHAR(50) NOT NULL
);
CREATE TABLE registrations (
student_id INTEGER NOT NULL,
course_id INTEGER NOT NULL,
PRIMARY KEY (student_id, course_id),
FOREIGN KEY (student_id) REFERENCES students(id),
FOREIGN KEY (course_id) REFERENCES courses(id)
);
INSERT INTO students (id, name) VALUES (1, 'Alice');
INSERT INTO students (id, name) VALUES (2, 'Bob');
INSERT INTO students (id, name) VALUES (3, 'Charlie');
INSERT INTO courses (id, name) VALUES (1, 'Database Systems');
INSERT INTO courses (id, name) VALUES (2, 'Computer Networks');
INSERT INTO courses (id, name) VALUES (3, 'Algorithms');
INSERT INTO registrations (student_id, course_id) VALUES (1, 1);
INSERT INTO registrations (student_id, course_id) VALUES (1, 2);
INSERT INTO registrations (student_id, course_id) VALUES (2, 1);
INSERT INTO registrations (student_id, course_id) VALUES (2, 3);
INSERT INTO registrations (student_id, course_id) VALUES (3, 2);
INSERT INTO registrations (student_id, course_id) VALUES (3, 3);
现在我们想要查找所有已经注册了所有的课程的学生,可以使用 DIVISION 操作:
SELECT student_id
FROM registrations
GROUP BY student_id
HAVING COUNT(*) = (SELECT COUNT(*) FROM courses);
这将会返回以下结果:
student_id
----------
1
这是因为只有学生 Alice 在 registrations
表中注册了所有的课程。
结论
JOIN 和 DIVISION 都是关系数据库中常用的操作,可以帮助我们处理复杂的关系数据。JOIN 操作可以将两个或多个表联合起来,而 DIVISION 操作可以查找满足一组条件的所有元组。在实际开发中,我们需要仔细考虑操作的类型和参数,以确保正确地处理数据。