专注于“尝试学习JOIN
和LEFT JOIN
”部分的差异,当您想要查看一个表中的所有行时,外连接非常有用,即使是在另一个相关表中没有对应行的行。
这是一个使用学生和考试成绩的简单示例。
create table students (student_id serial primary key, student_name text);
create table tests (test_id serial primary key, test_name text, test_date date);
create table grades (
student_id int,
test_id int,
grade char,
primary key (student_id, test_id),
foreign key (student_id) references students (student_id),
foreign key (test_id) references tests (test_id));
insert into students (student_name) values ('joe');
insert into students (student_name) values ('amber');
insert into students (student_name) values ('steve');
insert into tests (test_name, test_date) values ('test 1', '2013-01-20');
insert into tests (test_name, test_date) values ('test 2', '2013-02-10');
insert into grades (student_id, test_id, grade) values (1, 1, 'A');
insert into grades (student_id, test_id, grade) values (1, 2, 'B');
insert into grades (student_id, test_id, grade) values (2, 1, 'B');
insert into grades (student_id, test_id, grade) values (2, 2, 'A');
以下查询将返回学生及其成绩的列表,其中包括一行标识尚无任何成绩的学生(在本例中为 Steve):
select s.student_name, t.test_name, t.test_date, g.grade
from students as s
left join grades as g on s.student_id = g.student_id
left join tests as t on g.test_id = t.test_id;
student_name | test_name | test_date | grade
--------------+-----------+------------+-------
joe | test 1 | 2013-01-20 | A
joe | test 2 | 2013-02-10 | B
amber | test 1 | 2013-01-20 | B
amber | test 1 | 2013-01-20 | A
steve | | |
(5 rows)
使用外连接的一种非常有用的方法是,当您只想查看相关表中没有匹配行的行时。您也可以使用子查询来执行此操作,但使用外连接并不是一个坏选择:
select s.student_name
from students as s
left join grades as g on s.student_id = g.student_id
where g.student_id is null;
student_name
--------------
steve
(1 row)
...在功能上等同于:
select student_name from students where student_id not in (select student_id from grades);
student_name
--------------
steve
(1 row)