我有两张桌子:class张和student张.我想得到所有现有的班级,并得到学生的数量(计数)每个给定的班级.诀窍是,我还想展示一个有0名学生的班级.

表"class":

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');

表"student":

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_name class_id num_students
A 1 3
B 2 2

我很希望能够得到这样的东西:

class_name class_id num_students
A 1 3
B 2 2
C 3 0

推荐答案

从描述中可以看出,您的查询似乎是为了回答问题"对于每个班级,注册了多少不同的学生?"不幸的是,您编写的查询回答了一个略有不同的问题;即,"对于每个至少有一个注册学生的班级,有多少独立的学生注册?"

为了可读性和清晰度,我建议在第FROM条中把class放在第一位,因为它是驱动表.对于包含多个表的查询,请始终限定列名,以便在不必引用每个表的DDL的情况下轻松识别源.在 Select 列表中,只在必要时引用外部联接表中的列,因为如果不满足联接条件,它们将是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的其他列包括在分组表达式列表中是多余的,因 for each 列都完全依赖于class_id.

引用class(class_id)student(class_id)上应该有外键约束.

Sql相关问答推荐

Microsoft Access UNION将长文本字段限制为255个字符

获取每个帖子的匹配关键字列表

SQL更新,在2个额外的表上使用内部连接

对非RUST源代码字符串使用`stringify!`,例如SQL查询

雅典娜嵌套Json提取液

PostgreSQL:按小时查看调整日期

DBeaver将过程中的属性列表转换为字符串

两个不同星期的销售额,不加成一行

正在编写查询.我需要将订阅的时间段分为第一个订阅中包含的另一个订阅之前和之后的时间段

如何在连接中使用三个不同的列,从而在PostgreSQL中只获得两个列?

STContains、STIntersections和STWithin返回错误的地理结果

将二维数组的第一个和第二个元素取消嵌套到两个一维数组中

根据标识符将两行合并为一行

Select 一个非零值减少重复

SQL:考虑合并分支计算分支的增长百分比

如何在TSQL中编写此窗口查询

批量更改WooCommerce中所有产品的税收状态

我如何编写一个遍历数组数组并将所有值连接成一个字符串的 postgres 函数

如何筛选 GROUP BY 结果? HAVING 没有产生预期的结果

使用标准SQL 触发更新当前日期