我有两张桌子:
class
和student
。我想获取所有现有班级并获取每个给定班级的学生人数(计数)。技巧是我还想显示一个有 0
学生的班级。
表“类”:
DROP TABLE IF EXISTS "class";
CREATE TABLE class(
class_id SERIAL PRIMARY KEY,
class_name VARCHAR
);
INSERT INTO class (class_name) VALUES ('A');
INSERT INTO class (class_name) VALUES ('B');
INSERT INTO class (class_name) VALUES ('C');
表“学生”:
DROP TABLE IF EXISTS "student";
CREATE TABLE student(
student_id SERIAL PRIMARY KEY,
student_name VARCHAR,
class_id numeric
);
INSERT INTO student (student_name, class_id) VALUES ('Mike', 1);
INSERT INTO student (student_name, class_id) VALUES ('Jessica', 1);
INSERT INTO student (student_name, class_id) VALUES ('Thomas', 1);
INSERT INTO student (student_name, class_id) VALUES ('Jacob', 2);
INSERT INTO student (student_name, class_id) VALUES ('Izabella', 2);
我的查询有效,但
NOT
是否显示班级 C
和 0
学生:
SELECT class_name, student.class_id, COUNT(DISTINCT student_id) AS num_students
FROM student
LEFT JOIN class ON student.class_id = class.class_id
GROUP BY student.class_id, class.class_name;
以上查询给出了以下结果:
类名 | class_id | num_学生 |
---|---|---|
A | 1 | 3 |
B | 2 | 2 |
我希望能够得到这样的东西:
类名 | class_id | num_学生 |
---|---|---|
A | 1 | 3 |
B | 2 | 2 |
C | 3 | 0 |
从描述来看,您的查询似乎旨在回答“对于每个班级,有多少名独特的学生注册?”的问题。不幸的是,您编写的查询回答了一个略有不同的问题;即“对于每个至少有一名注册学生的班级,注册了多少名独特的学生?”
为了可读性/清晰度,我建议将
class
放在 FROM
子句中,因为它是驱动表。对于包含多个表的查询,请始终限定列名称,以便轻松识别源,而无需引用每个表的 DDL。在选择列表中,仅在必要时引用外部连接表中的列,因为如果不满足连接条件,它们将是 NULL
。
以下查询产生请求的结果:
SELECT class.class_name, class.class_id, COUNT(DISTINCT student.student_id) AS num_students
FROM class
LEFT JOIN student
ON class.class_id = student.class_id
GROUP BY class.class_id
ORDER BY class.class_name;
请注意,此查询仅按
class.class_id
分组。由于 class_id
是主键,因此在分组表达式列表中包含 class
中的其他列是多余的,因为每个列都完全依赖于 class_id
。
对
student(class_id)
引用 class(class_id)
应该有外键约束。